SQL 在两个表中按计数分组

SQL group by count across two tables

我有两个 table 称为基线和重访

基线

formid-------NoOfIssues

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

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

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

回访次数

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

这些 table 由 'formid' 加入。 我需要比较基线中的问题数量与重访(仅第一次)并得到 减少增加 相等的计数

基于上述 table 我期待以下结果,例如,在所有三个基线条目中,没有发现与第一次重访时的 NoOfissues 与相同 formid 的相等,但发现 1 个相等和 2 个增加

补充:如果找到相同的日期和相同的formid而不取较低的fid,所以在最后两行重访table formid和date都相等但需要考虑较低的formid,即1

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

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

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

increased--------2

我会在一行而不是三行中执行此操作:

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;

我不熟悉 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

关于您的数据库的一些快速说明 - 您可能应该决定复数或单数 table 名称的标准并坚持使用。此外,尽量避免对象名称的常见保留字,如日期。最后,如果重访与访问基本相同,只是在以后的某个日期,那么您应该考虑将它们全部保持在同一 table.

我会使用 window 函数来获取最短日期的使用次数,然后将其与基线问题数量进行比较

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 

或者像这样:

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;