我一直在玩关于重复的不同查询,但这不是我真正需要的。我确实需要一个重复列表,但另一列中的值不同。
我正在尝试在SQL Server 2012中执行此操作。
我需要获取一个“重复”行的列表,其中DocId是相同的,但它们在表中有不同的PoId。
AuditId|DocMasterId|PoNumber
2224 |105 |11111
2374 |105 |11111
2574 |105 |11112
2624 |106 |232323
2874 |106 |242424
基于上述内容的查询应返回
105 106
但理想情况下,如果我可以根据相同的DocMasterId列出每个不同采购订单的第一个和最后一个条目,那将是理想的解决方案,所以我最终会
AuditId|DocMasterId|PoNumber
2224 |105 |11111
2574 |105 |11112
2624 |106 |232323
2874 |106 |242424
关于如何在SQL中实现这一点的任何想法?
感谢。
更新:
我应该澄清一下,我只想列出有PONumber设置的行,我希望我的结果按DocMasterId排序。
根据Tim的回答,最终结果如下:
WITH CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
RN_ASC = ROW_NUMBER() OVER (PARTITION BY DocMasterID ORDER BY
PoNumber ASC),
RN_DESC = ROW_NUMBER() OVER (PARTITION BY DocMasterID ORDER BY
PoNumber DESC),
CNT = COUNT(*) OVER (PARTITION BY DocMasterID)
FROM dbo.MyTable
WHERE PONumber IS NOT NULL
)
SELECT AuditId, DocMasterId, PoNumber
FROM CTE
WHERE CNT >= 2
AND (RN_ASC = 1 OR RN_DESC = 1)
ORDER BY DocMasterId
答案 0 :(得分:2)
select AuditId, DocMasterId, PoNumber
from ( select *, ROW_NUMBER() OVER (PARTITION BY DocMasterId, PoNumber ORDER BY DocMasterId ASC) as a from tablename ) abc
where a =1
我使用DocMasterId和PoNumber创建了一个分区列,它将为DocMasterId,PoNumber的每个相同值重复Row_Number。然后我使用条件a = 1
删除了重复记录答案 1 :(得分:1)
这种方法使用排名函数和CTE:
WITH CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
RN_ASC = ROW_NUMBER() OVER (PARTITION BY DocMasterID ORDER BY PoNumber ASC),
RN_DESC = ROW_NUMBER() OVER (PARTITION BY DocMasterID ORDER BY PoNumber DESC),
CNT = COUNT(*) OVER (PARTITION BY DocMasterID)
FROM dbo.TableName
)
SELECT AuditId, DocMasterId, PoNumber
FROM CTE
WHERE CNT >= 2
AND (RN_ASC = 1 OR RN_DESC = 1)
ORDER BY DocMasterId
根据您的评论更新NULL
中的PoNumber
值应排除在外,不计入CNT
:
WITH CTE AS
(
SELECT AuditId, DocMasterId, PoNumber,
RN_ASC = ROW_NUMBER() OVER (PARTITION BY DocMasterID
ORDER BY CASE WHEN PoNumber IS NULL THEN 1 ELSE 0 END ASC,
PoNumber ASC),
RN_DESC = ROW_NUMBER() OVER (PARTITION BY DocMasterID ORDER BY PoNumber DESC),
CNT = SUM(CASE WHEN PoNumber IS NOT NULL THEN 1 END) OVER (PARTITION BY DocMasterID)
FROM dbo.TableName
)
SELECT AuditId, DocMasterId, PoNumber
FROM CTE
WHERE CNT >= 2
AND (RN_ASC = 1 OR RN_DESC = 1)
ORDER BY DocMasterId
Demo ,您的样本数据无法正确返回任何记录。
答案 2 :(得分:0)
如果您的数据库支持Window功能,请尝试使用
;WITH cte
AS (SELECT Row_number()OVER(partition BY DocMasterId
ORDER BY AuditId DESC) a_rn,
Row_number()OVER(partition BY DocMasterId
ORDER BY AuditId ) d_rn,
*
FROM Yourtable)
SELECT AuditId,
DocMasterId,
PoNumber
FROM cte
WHERE a_rn = 1 or D_rn =1
答案 3 :(得分:0)
只需GROUP BY
?
select min(AuditId), DocMasterId, PoNumber
from tablename
group by DocMasterId, PoNumber