简体   繁体   English

SQL按两个表的计数分组

[英]SQL group by count across two tables

I have got two tables called baseline and revisits 我有两个表叫做baseline,然后重新访问

baseline 基准线

formid-------NoOfIssues

1--------------3

2--------------4

3--------------5

revisits 重访

id------formid-------NoOfIssues-----------date--------------fid

1---------2--------------4-------------5/06/2016------------1

2---------3--------------3-------------15/06/2016-----------1

3---------1--------------4-------------20/07/2016-----------1

4---------1--------------3-------------25/07/2016-----------1

5---------2--------------5-------------28/07/2016-----------1

6---------1--------------5-------------01/06/2016-----------1

7---------3--------------8-------------21/02/2016-----------1

8---------3--------------2-------------21/02/2016-----------2

These tables are joined by 'formid'. 这些表由“ formid”连接。 I need to compare number of issues in baseline vs revisits(only first) and get a count as reduced , increased or equal 我需要比较基线与重访的问题数量(仅第一时间),并获得减少增加等于的计数

Based upon the above table i am expecting the following, for example across all three baseline entries no equals were found comparing NoOfissues in first revisit against same formid, but 1 equal and 2 increased were found 基于上表,我希望得出以下结果,例如,在所有三个基线条目中,没有发现相等的结果,将第一次重访的NoOfissues与相同的甲虫进行比较,但是发现1个相等,而2个增加了

Addition: if same date and same formid is found than take the lower fid, so in the last two rows of revisits table both formid and date are equal but need to consider the lower formid which is 1 加法:如果发现相同的日期和相同的残缺而不是较低的fid,那么在重新访问表的最后两行中,残缺和日期均相等,但需要考虑较低的残缺为1

status----------Count

reduced----------0

equal------------1

increased--------2

I would do this in one row rather than three: 我会连续执行此操作,而不是三行:

select sum(case when numissues = rcnt then 1 else 0 end) as equal,
       sum(case when numissues > rcnt then 1 else 0 end) as reduced,
       sum(case when numissues < rcnt then 1 else 0 end) as incrased
from (select b.form_id, b.numissues, count(r.form_id) as rcnt
      from baseline b left join
           revisits r
           on b.form_id = r.form_id
      group by b.form_id, b.numissues
     ) br;

I'm not familiar with intersystems-cache, but you can see if the following is valid SQL with that DB: 我对intersystems-cache不熟悉,但是您可以看到以下内容对于该数据库是否是有效的SQL:

SELECT
    CASE
        WHEN BL.NoOfIssues = FR.NoOfIssues THEN 'equal'
        WHEN BL.NoOfIssues > FR.NoOfIssues THEN 'reduced'
        WHEN BL.NoOfIssues < FR.NoOfIssues THEN 'increased'
    END AS status,
    COUNT(*) AS Count
FROM
    Baseline BL
INNER JOIN Revisits FR ON FR.formid = BL.formid
LEFT OUTER JOIN Revisits R ON
    R.formid = BL.formid AND
    (
        R.date < FR.date OR
        (R.date = FR.date AND R.fid > FR.fid)
    )
WHERE
    R.formid IS NULL
GROUP BY
    CASE
        WHEN BL.NoOfIssues = FR.NoOfIssues THEN 'equal'
        WHEN BL.NoOfIssues > FR.NoOfIssues THEN 'reduced'
        WHEN BL.NoOfIssues < FR.NoOfIssues THEN 'increased'
    END

Some quick notes on your database though - You should probably decide on a standard of plural or singular table names and stick with it. 但是,关于数据库的一些快速注释-您可能应该决定使用复数或单数表名的标准并坚持使用。 Also, try to avoid common reserved words for object names, like date. 另外,请尽量避免使用对象名称(例如日期)这样的通用保留字。 Finally, if a revisit is basically the same as a visit, just on a later date then you should consider keeping them all in the same table. 最后,如果重访与访问基本相同,只是在以后的某个日期,则应考虑将它们全部保存在同一表中。

I would use a window function to get the number of ussues at the minimum date, then compare that to the baseline number of issues 我将使用窗口函数来获取最短日期的使用人数,然后将其与基线发行量进行比较

select
    case when baseline.NoOfIssues = rev.NoOfIssues then 'equal'
         when baseline.NoOfIssues > rev.NoOfIssues then 'reduced'
         when baseline.NoOfIssues < rev.NoOfIssues then 'increased'
    end as status,
    count(*) as count
from baseline
inner join(
    select
        formid,
        case when date = min(date) over(partition by formid) then NoOfIssues else null end as first_rev_issues
    from revisits
) rev
on baseline.formid = rev.formid
group by
    case when baseline.NoOfIssues = rev.NoOfIssues then 'equal'
         when baseline.NoOfIssues > rev.NoOfIssues then 'reduced'
         when baseline.NoOfIssues < rev.NoOfIssues then 'increased'
    end 

Or like this: 或像这样:

WITH CTE AS 
(
SELECT
BL.FORMID, 
BL.NOOFISSUES AS BLI, 
RV.NOOFISSUES AS RVI, 
RV.DATE,
ROW_NUMBER() OVER(PARTITION BY BL.FORMID ORDER BY RV.DATE) AS RN
FROM Baseline BL
INNER JOIN Revisits RV ON RV.FORMID = BL.FORMID
)

SELECT COALESCE(SUM(CASE WHEN RVI > BLI THEN 1 END), 0) AS INCREASED,
COALESCE(SUM(CASE WHEN RVI < BLI THEN 1 END), 0) AS DECREASED, 
COALESCE(SUM(CASE WHEN RVI = BLI THEN 1 END), 0) AS EQUAL
FROM CTE
WHERE RN=1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM