Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何在同一字段中获取Id相同但值不同的行列表_Sql_Sql Server - Fatal编程技术网

Sql 如何在同一字段中获取Id相同但值不同的行列表

Sql 如何在同一字段中获取Id相同但值不同的行列表,sql,sql-server,Sql,Sql Server,我一直在处理关于重复项的不同查询,但这并不是我真正需要的。我确实需要一个重复列表,但另一列中的值不同 我正试图在SQLServer2012中实现这一点 我需要得到一个“重复”行列表,其中DocId相同,但表中的PoId不同 AuditId|DocMasterId|PoNumber 2224 |105 |11111 2374 |105 |11111 2574 |105 |11112 2624 |106 |232323 2874

我一直在处理关于重复项的不同查询,但这并不是我真正需要的。我确实需要一个重复列表,但另一列中的值不同

我正试图在SQLServer2012中实现这一点

我需要得到一个“重复”行列表,其中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

如果您的数据库支持窗口功能,请尝试以下操作

;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

该方法使用排序函数和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


根据您的评论进行更新,
PoNumber
中的
NULL
值应排除在外,且不计入
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

您的样本数据不会正确返回任何记录。

简单地
分组依据

select min(AuditId), DocMasterId, PoNumber
from tablename
group by DocMasterId, PoNumber

我使用DocMasterId和PoNumber创建了一个分区列,它将为DocMasterId的每个相同值PoNumber重复行号。然后我使用where条件a=1消除了重复记录

您可以使用Group by“where the DocId is same..have a different PoId”您没有显示任何这些列。“如果我能列出每个副本的第一个和最后一个条目,那将是理想的解决方案”指定第一个和最后一个。另外:您使用的是哪种DBMS?博士后?Oracle?如果多个DocMasterId、PoNumber重复,如何选择试镜?(2224或2374?)嗨,对不起,我已经澄清了这个问题。我是SQL Server 2012,理想情况下,我希望获得在同一DocMasterId下列出的每个条目的第一个PO编号和最后一个PO编号记录的列表。谢谢Tim!你太棒了!我不得不稍微修改一下查询,因为我忘了提到我的PONumber不是空的,它必须按DocMasterId排序,但一旦更改,它就起了作用!!我马上发布我的更新查询。我们刚刚在一个实时数据库上运行了此查询,返回的结果不正确。我们的一些PONUMBER是空的,但它似乎仍然将它们作为已更改的值包含在内。知道我们如何从查询中排除这些吗?我原以为我在上面更新的查询会成功,但事实并非如此。@Thierry:您的查询似乎是正确的。如果
PONumber
NULL
,则不应存在任何记录。您可以通过以下方式进行验证:
。。。从CTE中选择*,其中PONumber为空
,不产生任何记录。这些值可能是
NULL
varchar
值)或只是空的。请尝试这些值(32101823,NULL),(32102823,NULL),(59252823,'PO201300057'),(1017082823,'PO201300057'),(1017084823,'PO201300057'),(1017090823,'PO201300057'),并将PONumber更改为NVARCHAR(15)。这将返回一行,而我们实际上应该什么都没有。奇怪的是,我们创建了一个视图来排除所有为null的PONumber,并对该视图运行了查询,它仍然返回DocMasterId 823,以及其他许多属于这种情况的PONumber!非常奇怪@蒂埃里:我现在要回家了,但我还是注意到了一些问题。但也许它对你有帮助。你可以添加一些解释吗?@AdrianCidAlmaguer解释:我使用
DocMasterId
PoNumber
创建了一个分区列,它将对
DocMasterId,PoNumber
的每个相同值重复
行号。然后我使用where条件
a=1
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