Sql server 具有唯一字段的T-SQL返回行
我得到了以下CTE表达式:Sql server 具有唯一字段的T-SQL返回行,sql-server,tsql,Sql Server,Tsql,我得到了以下CTE表达式: WITH DocDetails_CTE AS ( SELECT d.DocumentId, dd.AutUser, rank() over (order by d.DocumentId) as [r] FROM Document d INNER JOIN DocumentItems di ON d.DocumentId = di.Docu
WITH DocDetails_CTE
AS
(
SELECT d.DocumentId,
dd.AutUser,
rank() over (order by d.DocumentId) as [r]
FROM Document d
INNER JOIN DocumentItems di
ON d.DocumentId = di.DocumentId
INNER JOIN DocumentDetails dd
ON dd.DocumentDetailsId = di.DocDetailsId
)
SELECT *
FROM DocDetails_CTE
返回以下结果:
documentId| AuthUser | [r]
-------------------------------
52 Derck 1
52 John 1
53 Niall 3
53 Bill 3
53 John 3
53 Andy 3
54 Rob 7
54 Noel 7
如何修改CTE,以便只获取具有新documentId的第一行
e、 g
你必须决定“第一行”是什么意思——通过手工制作min
或max
或其他方法来确定你想要的行。这将按字母顺序返回“第一个”:-
select cte.DocumentId, min(cte.AutUser) as AutUser, cte.[r]
from (
SELECT d.DocumentId,
dd.AutUser,
rank() over (order by d.DocumentId) as [r]
FROM Document d
INNER JOIN DocumentItems di
ON d.DocumentId = di.DocumentId
INNER JOIN DocumentDetails dd
ON dd.DocumentDetailsId = di.DocDetailsId
) cte
group by cte.DocumentId, cte.[r]
或者,您可以嵌套两个窗口函数并复制(可能)随机代码:-
select
pass2.documentid,
pass2.autuser,
pass2.r
from (
select
pass1.*,
row_number() over (partition by [r] order by documentid ) as rownumber
from (
select
d.documentid,
dd.autuser,
rank() over (order by d.documentid) as [r]
from document d
join documentitems di on di.documentid = d.documentid
join documentdetails dd on dd.documentdetailsid = di.docdetailsid
) pass1
) pass2
where pass2.rownumber=1
你必须决定“第一行”是什么意思——通过手工制作min
或max
或其他方法来确定你想要的行。这将按字母顺序返回“第一个”:-
select cte.DocumentId, min(cte.AutUser) as AutUser, cte.[r]
from (
SELECT d.DocumentId,
dd.AutUser,
rank() over (order by d.DocumentId) as [r]
FROM Document d
INNER JOIN DocumentItems di
ON d.DocumentId = di.DocumentId
INNER JOIN DocumentDetails dd
ON dd.DocumentDetailsId = di.DocDetailsId
) cte
group by cte.DocumentId, cte.[r]
或者,您可以嵌套两个窗口函数并复制(可能)随机代码:-
select
pass2.documentid,
pass2.autuser,
pass2.r
from (
select
pass1.*,
row_number() over (partition by [r] order by documentid ) as rownumber
from (
select
d.documentid,
dd.autuser,
rank() over (order by d.documentid) as [r]
from document d
join documentitems di on di.documentid = d.documentid
join documentdetails dd on dd.documentdetailsid = di.docdetailsid
) pass1
) pass2
where pass2.rownumber=1
我只想在新的documentId出现时显示该行,如上所示。但是“出现”是什么意思?在您的示例中,为什么选择Derck而不是John作为documentId 1?为什么是尼尔而不是比尔、约翰和安迪?您的代码将根据聚集索引键和表统计信息生成不同的答案,这导致查询优化器采用不同的执行计划。您通常希望保护自己不受这种调试时难以发现的“随机”行为的影响。感谢您的详细回复,是的,我只想为每个documentId返回一行。所以对于DocumentID52,我想要john或Derck,但不是两者都想要。我需要为每个documentId获取一行。感谢第二个解决方案工作完美,因为它消除了对CTE的需要。公平竞争。-谢谢。我只想在新的documentId出现时显示行,如上所示。但是“出现”是什么意思?在您的示例中,为什么选择Derck而不是John作为documentId 1?为什么是尼尔而不是比尔、约翰和安迪?您的代码将根据聚集索引键和表统计信息生成不同的答案,这导致查询优化器采用不同的执行计划。您通常希望保护自己不受这种调试时难以发现的“随机”行为的影响。感谢您的详细回复,是的,我只想为每个documentId返回一行。所以对于DocumentID52,我想要john或Derck,但不是两者都想要。我需要为每个documentId获取一行。感谢第二个解决方案工作完美,因为它消除了对CTE的需要。公平竞争-谢谢。