sql - 如何根据日期和相同的 PK 个人编号找到两个总和的差异
问题描述
我需要找到重复的个人 ID 并确定哪些个人 ID 得到了改进。例如,对于每个 IndividualID,我需要 C_Q1、C_Q2、C_Q3、C_Q4、C_Q5 的总和,并根据日期和 1 是最大的改进,5 是最小的改进,如果第二个总和小于第一个数字,并将通过 UpdateDate 确定第一个数字是最早的日期,第二个数字是较晚的日期。对于 Anxiety_Arr、Hyper_Arr、Exagg_Arr、Anxiety_Dep、Hyper_Dep、Exagg_Dep,1 是最小的改进,0 是最大的改进,因此在将它们相加后,如果第二个总和小于第一个总和,则将计算在内。
这是获得我需要的总和的代码,但随后需要帮助来了解如何比较每个 individualID 的第一个和第二个数字以及第二个总和低于第一个总和的个人计数。
select distinct
IND.Individuals_IndividualID
, C.ATQChild_IndividualID
, ANS.ANS_IndividualID
, C.UpdateDate as ATQChild_UpdateDate
, ANS.UpdateDate as ANS_UpdateDate
, c.q1_c as C_Q1
, c.q2_c as C_Q2
, c.q3_c as C_Q3
, c.q4_c as C_Q4
, c.q5_c as C_Q5
, Sum(isnull(cast(Q1_c as int),0)) + Sum(isnull(cast(Q2_c as int),0)) + Sum(isnull(cast(Q3_c as int),0)) + Sum(isnull(cast(Q4_c as int),0)) + Sum(isnull(cast(Q5_c as int),0)) as ChildSum
, Sum(isnull(cast(anxiety_arr as int),0)) + Sum(isnull(cast(hyper_arr as int),0)) + Sum(isnull(cast(exagg_arr as int),0)) as ANS_ArrSum
, Sum(isnull(cast(anxiety_dep as int),0)) + Sum(isnull(cast(hyper_dep as int),0)) + Sum(isnull(cast(exagg_dep as int),0)) as ANS_DepSum
, CASE WHEN (ANS.[anxiety_arr])='TRUE' THEN 1 ELSE 0 END as Anxiety_Arr
, CASE WHEN (ANS.[hyper_arr])='TRUE' THEN 1 ELSE 0 END as Hyper_Arr
, CASE WHEN (ANS.[exagg_arr])='TRUE' THEN 1 ELSE 0 END as Exagg_Arr
, CASE WHEN (ANS.[anxiety_dep])='TRUE' THEN 1 ELSE 0 END as Anxiety_Dep
, CASE WHEN (ANS.[hyper_dep])='TRUE' THEN 1 ELSE 0 END as Hyper_Dep
, CASE WHEN (ANS.[exagg_dep])='TRUE' THEN 1 ELSE 0 END as Exagg_Dep
from DBO.tb_cdcp_individuals ind
left join DBO.tb_cdcp_ATQChild c on c.[tb_cdcp_individuals] = ind.[tb_cdcp_individuals]
left join DBO.tb_cdcp_ans_checklist ANS on ans.[tb_cdcp_individuals] = ind.[tb_cdcp_individuals]
group by IND.tb_cdcp_individuals,C.[tb_cdcp_individuals],ANS.[tb_cdcp_individuals],C.UpdateDate,ANS.UpdateDate
, c.q1_c
, c.q2_c
, c.q3_c
, c.q4_c
, c.q5_c
, ANS.Anxiety_Arr
, ANS.hyper_arr
, ANS.exagg_arr
, ANS.Anxiety_Dep
, ANS.Hyper_Dep
, ANS.Exagg_Dep
解决方案
您可以使用滞后/领先功能来比较 ID 的连续记录。例如,对于以下示例(假设表名为 temp):
身份证日期 CQ1To5
2019 年 1 月 1 日 10
2019 年 1 月 2 日 5
select *,lag(CQ1To5,1) Over(Partition by ID Order by Date) as lag_date,
Case when lag(CQ1To5,1) Over(Partition by ID Order by Date) is NULL then 0
when lag(CQ1To5,1) Over(Partition by ID Order by Date)<CQ1To5 then 1 else 0 end as Flag from temp
这应该为您提供以下输出:
ID 日期 CQ1To5 Lag_date 标志
2019 年 1 月 1 日 10 5 1
1 2019 年 1 月 2 日 5 空 0
只要 ID 的下一条记录是改进的,您的标志值就应该是 1。您可以修改此查询以满足您的特定需求。希望这可以帮助。
注意:CQ1to5 表示您提到的所有 5 个字段的总和
您可以使用连接和行号执行相同操作:
select *,Row_number() Over(Partition by ID Order by Date) as rownum
into #temp1
from #temp
select a.*,b.CQ1to5,case when a.CQ1to5<b.CQ1to5 then 1 else 0 end as flag
into #temp2
from #temp1 a left join #temp1 b on a.id=b.id and a.rownum=b.rownum+1
select *,row_number() over(Partition by ID,flag order by Date) as rownum1
into #temp3
from #temp2
UPDATE #temp3
SET flag=0
where flag=1 and rownum1>1
推荐阅读
- android - 特维利奥。通话在 wifi 关闭或应用程序终止时保持活动状态
- laravel - Laravel 审计 BadMethodCallException 方法审计不存在
- validation - Grails 中的电子邮件验证
- angular - 使用 Angular 5 HttpClient Request 下载 excel 文件
- javascript - JavaScript 事件侦听器不触发拖放
- jquery - 如何获取div内部的频繁值输出?
- javascript - 错误 Wordpress jquery 表单错误说未引用的函数?
- polymer-3.x - 在 stackblitz 中找不到包,即使它存在于 npm 网站中。那怎么安装呢?
- appium - 如何使用 Appium 启用/禁用应用程序权限?
- python - 如何在文本 PYTHON 中插入两个以上的变量