SQL - 如果组中的所有内容都相同,则更新字段

时间:2015-12-18 17:49:28

标签: sql sql-server tsql

我有一个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

4 个答案:

答案 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);

希望有所帮助。

如果您想让它自动化,那么您可能需要查看触发器。