我正在使用以下SELECT从数据库中获取数据。
有没有办法按嵌套选择中的项目排序结果?
我尝试ORDER BY B.ID
,但这会产生错误。
我的存储过程:
SELECT (
SELECT B.ID,
B.FirstName,
B.LastName
FROM Users B
WHERE B.UserNum = A.UserNum
FOR XML PATH(''), ELEMENTS, TYPE
)
FROM User_SolutionRole A
WHERE A.Solution = 'SPR'
FOR XML PATH('users'), ELEMENTS, TYPE, ROOT('ranks')
答案 0 :(得分:4)
如果我们可以将values()
method应用于SELECT的唯一列以从中提取ID
值,我们可以使用结果对行进行排序,如下所示:
<column_ref>.values('ID[1]', 'int') ASC
实际上可以实现这一目标。如果您为该列指定了名称users
,同时将PATH('users')
替换为PATH('')
,如下所示:
SELECT (
SELECT B.ID,
B.FirstName,
B.LastName
FROM Users B
WHERE B.UserNum = A.UserNum
FOR XML PATH(''), ELEMENTS, TYPE
) AS users
FROM User_SolutionRole A
WHERE A.Solution = 'SPR'
FOR XML PATH(''), ELEMENTS, TYPE, ROOT('ranks')
;
你会获得相同的输出,但该列现在将有一个参考。那将是你迈向目标的第一步。
看起来你只需要像这样添加一个ORDER BY:
SELECT (
SELECT B.ID,
B.FirstName,
B.LastName
FROM Users B
WHERE B.UserNum = A.UserNum
FOR XML PATH(''), ELEMENTS, TYPE
) AS users
FROM User_SolutionRole A
WHERE A.Solution = 'SPR'
ORDER BY users.value('ID[1]', 'int') ASC
FOR XML PATH(''), ELEMENTS, TYPE, ROOT('ranks')
;
然而,这不起作用,因为在SELECT子句中分配的别名只能由与相同的ORDER BY子句引用,即它不能是一个表达。所以上面会导致编译错误。
解决方法是将名称 previous 分配给主SELECT。基本上有两种方式:
使用派生表:
SELECT users
FROM (
SELECT (
SELECT B.ID,
B.FirstName,
B.LastName
FROM Users B
WHERE B.UserNum = A.UserNum
FOR XML PATH(''), ELEMENTS, TYPE
) AS users
FROM User_SolutionRole A
WHERE A.Solution = 'SPR'
) AS s
ORDER BY users.value('ID[1]', 'int') ASC
FOR XML PATH(''), ELEMENTS, TYPE, ROOT('ranks')
;
以上使用“普通”子选择,但如果您将其声明为CTE则没有区别。
使用CROSS APPLY
:
SELECT x.users
FROM User_SolutionRole A
CROSS APPLY (
SELECT B.ID,
B.FirstName,
B.LastName
FROM Users B
WHERE B.UserNum = A.UserNum
FOR XML PATH(''), ELEMENTS, TYPE
) AS x (users)
WHERE A.Solution = 'SPR'
ORDER BY x.users.value('ID[1]', 'int') ASC
FOR XML PATH(''), ELEMENTS, TYPE, ROOT('ranks')
;
我个人的偏好是CROSS APPLY technique看起来更简单,(对我来说)更清晰,但former method同样有效。