我有一个22列多行的表。
我想获得一个新表,它将只包含列V1, V3, V4, V13中的值在表中相互关联(这些重复)出现两次的行
Works in Microsoft SQL Server Management Studio.
我试过这样做
SELECT
V1, V3, V4, V13
FROM
table
GROUP BY
V1, V3, V4, V13
HAVING
(COUNT (*) = 2)
您可以先计算每个">V1", ">V3", ">V4", ">V13"字段与COUNT
窗口函数。然后连接回原始表,但保留那些计数大于1的行。
WITH cte AS (
SELECT <your_table_identifier_field(s)>,
COUNT(*) OVER(PARTITION BY V1, V3, V4, V13) as cnt
FROM table
)
SELECT *
FROM tab
INNER JOIN cte
ON tab.<your_table_identifier_field(s)> = cte.<your_table_identifier_field(s)>
AND cte.cnt > 1
编辑:如果没有特定的行标识符怎么办?您将被迫匹配所有列值。
WITH cte AS (
SELECT *,
COUNT(*) OVER(PARTITION BY V1, V3, V4, V13) as cnt
FROM table
)
SELECT *
FROM tab
INNER JOIN cte
ON tab.<field1> = cte.<field1>
AND tab.<field2> = cte.<field2>
AND ...
AND cte.cnt > 1
为什么要把事情复杂化呢?只需将原始查询放入CTE中,然后将CTE连接到原始表。
with cte as (
SELECT V1, V3, V4, V13 FROM dbo.table
GROUP BY V1, V3, V4, V13
HAVING COUNT (*) > 1
)
select t1.*
from dbo.table as t1
inner join cte on t1.V1 = cte.V1 and t1.V2 = cte.V2 ...
order by ...
;
我已经做了一些更改,以纳入最佳实践。将模式名(假设是dbo)添加到表名、语句结束符、ORDER BY子句(因为它通常很重要)。我更改了HAVING子句,因为你要求副本,这意味着计数是>1. 使用count = 2意味着将结果限制在恰好的行中。两个副本。这是一个非常不寻常的要求,但如果需要的话可以更改它。通常我不会使用"*"作为列列表,通常最好显式地包含所需的列。这也留给你了。
最后,考虑更改模式以防止重复。这将避免很多未来的工作。