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;
我有两个 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;