在具有重复行的 SQL Server 表中按组查找行号
Posted
技术标签:
【中文标题】在具有重复行的 SQL Server 表中按组查找行号【英文标题】:find row number by group in SQL server table with duplicated rows 【发布时间】:2015-05-18 22:16:50 【问题描述】:我需要在有一些重复的表中按组计算行号。
表:
id va1ue1 value2
1 3974 39
1 3974 39
1 972 5
1 972 10
SQL:
select id, value1, value2, COUNT(*) cnt
FROM table
group by id, value1, value2
having COUNT(*) > 1
代码只计算重复的行。 我需要:
id, value1, value2
1 972 5
1 972 10
我不需要计算重复的行,我只需要 value1 在 value2 列中具有多个不同值的行。
谢谢
【问题讨论】:
【参考方案1】:使用DISTINCT
:
select id, value1, count(distinct value2) cnt
from table
group by id, value1
having count(distinct value2) > 1
如果您想了解详细信息,那么:
select * from table t1
cross apply(select cnt from(
select count(distinct value2) cnt
from table t2
where t1.id = t2.id and t1.value1 = t2.value1) t
where cnt > 1)ca
【讨论】:
【参考方案2】:在 SQL Server 2008 中,您可以使用一种技巧来使用窗口函数对不同的值进行计数。您可能会发现这是一个不错的解决方案:
select t.id, t.value1, t.value2
from (select t.*, sum(case when seqnum = 1 then 1 else 0 end) over (partition by value1) as numvals
from (select t.*, row_number() over (partition by value1, value2 order by (select null)) as seqnum
from table t
) t
) t
where numvals > 1;
【讨论】:
COUNT(DISTINCT) OVER
是在哪个版本中修复的?
@AndriyM 。 . .糟糕,我在考虑 Oracle。【参考方案3】:
在没有GROUP BY
的情况下尝试这种方式:
select id, value1, value2
FROM table AS T1
where 1 < (
select COUNT(*)
FROM table AS T2
where T1.value1 = T2.value1)
【讨论】:
【参考方案4】:试试这个
;WITH CTE
AS ( SELECT id ,
value1 ,
value2 ,
COUNT(*) cnt
FROM table
GROUP BY id ,
value1 ,
value2
HAVING COUNT(*) > 1
)
SELECT *
FROM table1
WHERE value1 IN ( SELECT value1
FROM CTE )
【讨论】:
【参考方案5】:只需在HAVING
之后使用NOT
,即可准确获取不重复的行。
select id, value1, value2
FROM [table]
group by id, value1, value2
having NOT COUNT(*) > 1
Fiddle here.
【讨论】:
【参考方案6】:如果您想要表中的实际行,而不仅仅是符合条件的 id, value1
对,您可以这样做:
WITH discrepancies AS (
SELECT,
id,
value1,
value2,
distinctcount = COUNT(DISTINCT value2) OVER (PARTITION BY id, value1)
FROM
dbo.atable
)
SELECT
id,
value1,
value2
FROM
discrepancies
WHERE
distinctcount > 1
;
如果 SQL Server 2008 支持 COUNT(DISTINCT ...)
和 OVER clause。
基本上,这与Giorgi Nakeuri's one 的想法差不多,只是你不会多次上桌。
唉,到目前为止还有no support for COUNT(DISTINCT ...) OVER ...
in SQL Server。不过,您可以使用不同的方法,它仍然允许您只触摸一次表格并返回详细信息行:
WITH discrepancies AS (
SELECT,
id,
value1,
value2,
minvalue2 = MIN(value2) OVER (PARTITION BY id, value1),
maxvalue2 = MAX(value2) OVER (PARTITION BY id, value1)
FROM
dbo.atable
)
SELECT
id,
value1,
value2
FROM
discrepancies
WHERE
minvalue2 <> maxvalue2
;
这里的想法是每个id, value1
获得MIN(value2)
和MAX(value2)
并查看它们是否不同。如果是这样,则意味着您在此 id, value1
子集中存在差异,并且您希望返回该行。
该方法利用带有 OVER 子句的聚合来避免自连接,这正是表在此处仅访问一次的原因。
【讨论】:
以上是关于在具有重复行的 SQL Server 表中按组查找行号的主要内容,如果未能解决你的问题,请参考以下文章