跨越两个表的SQL组

时间:2017-11-16 18:22:01

标签: sql intersystems-cache

我有两个叫做基线和重新访问的表

基线

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

这些表由'formid'连接。 我需要比较基线与重访的问题数量(仅限第一次)并计算为减少增加等于

基于上表,我期待以下情况,例如,在所有三个基线条目中,没有找到比较第一次重访中的NoOfissues与相同的formid,但发现1次相等和2次增加

另外:如果找到相同的日期和相同的formid而不是取下面的fid,那么在最后两行revisits表中,formid和date都相等但需要考虑下面的formid是1

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

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

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

increased--------2

4 个答案:

答案 0 :(得分:1)

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

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;

答案 1 :(得分:1)

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

关于您的数据库的一些快速说明 - 您应该决定复数或单数表名称的标准并坚持下去。另外,尽量避免使用对象名称的常用保留字,例如date。最后,如果重新访问与访问基本相同,那么您应该考虑将它们全部保存在同一个表中。

答案 2 :(得分:0)

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

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 

答案 3 :(得分:0)

或者像这样:

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;