我有一个SQL Server 2014临时表#SourceTable,如下所示,其中AllTheSamePerDOI是一个位字段,默认为0:
ID | DOI | Affiliations | SameAffiliationsPerDOI ----+-----+--------------+----------------------- 1 | 1 | Text A | 0 2 | 1 | Text A | 0 3 | 7 | Text CCC | 0 4 | 7 | Text CR | 0 5 | 7 | Text CCC | 0 6 | 9 | Text CCC | 0
我想要做的是,只有当同一DOI中的所有记录在该分组中的所有关联中具有完全相同的文本时,才将SameAffiliationsPerDOI字段设置为1。因此,最终结果看起来像DOI 1和DOI 9都有1组,因为每个DOI中的所有内容在所有记录的附属关系中都具有相同的值。如何编写SQL语句来执行此操作?
ID | DOI | Affiliations | SameAffiliationsPerDOI ----+-----+--------------+----------------------- 1 | 1 | Text A | 1 2 | 1 | Text A | 1 3 | 7 | Text CCC | 0 4 | 7 | Text CR | 0 5 | 7 | Text CCC | 0 6 | 9 | Text CCC | 1
答案 0 :(得分:2)
我喜欢使用可更新的CTE和窗口函数来解决这些问题:
with toupdate as (
select st.*,
min(Affiliations) over (partition by doi) as mina,
max(Affiliations) over (partition by doi) as maxa
from #SourceTable st
)
update toupdate
set SameAffiliationsPerDOI = 1
where mina = maxa;
您也可以使用not exists
:
update #SourceTable st
set SameAffiliationsPerDOI = 1
where not exists (select 1
from #SourceTable st2
where st2.doi = st.doi and st2.Affiliations <> st.Affiliations
);
哪个更快可能取决于数据中值的分布和可用的索引。
答案 1 :(得分:0)
这是使用dense_rank()窗口函数的解决方案:
with ranked as (
select DOI, dense_rank() over (partition by DOI order by Affiliations) r
from #SourceTable),
same as (select DOI from ranked group by DOI having max(r)=1)
update #SourceTable set SameAffiliationsPerDIO=1
where DOI in (select DOI from same)
答案 2 :(得分:0)
UPDATE S
SET SameAffiliationsPerDOI = 1
FROM #SourceTable S
WHERE NOT EXISTS (SELECT 1 FROM #SourceTable S2 WHERE S2.DOI = S.DOI AND S2.Affiliations <> S.Affiliations)
答案 3 :(得分:0)
所以根据我的理解,这是一次性更新?类似的未来案例不是持续更新?
如果是这样,那么尝试下面的SQL代码:
update #SourceTable
set SameAffiliationsPerDOI = 1
where ID in (1, 2, 6);
希望有所帮助。
如果您想让它自动化,那么您可能需要查看触发器。