Sql server SQL Server字符串\u AGG函数排序未按预期工作
我试图在一个动态生成的数据集上重现它,但最终还是解决了这个问题 这是密码Sql server SQL Server字符串\u AGG函数排序未按预期工作,sql-server,sql-server-2017,string-agg,Sql Server,Sql Server 2017,String Agg,我试图在一个动态生成的数据集上重现它,但最终还是解决了这个问题 这是密码 ;with tbl as ( select Id, ClCode, Manager, ChangeDate from (values (1, '000005', 'Cierra Vega', '2017-10-05'), (2, '000005', 'Alden Cantrell', '2017-11-29'), (3, '000005', 'Ald
;with tbl as
(
select Id, ClCode, Manager, ChangeDate
from (values
(1, '000005', 'Cierra Vega', '2017-10-05'),
(2, '000005', 'Alden Cantrell', '2017-11-29'),
(3, '000005', 'Alden Cantrell', '2017-11-30'),
(4, '000005', 'Kierra Gentry', '2018-09-05'),
(5, '000005', 'Kierra Gentry', '2018-09-12'),
(6, '000005', 'Pierre Cox', '2018-11-06'),
(7, '000005', 'Thomas Crane', '2019-09-11'),
(8, '000005', 'Thomas Crane', '2019-10-01'),
(9, '000005', 'Miranda Shaffer', '2020-04-27'),
(10,'000360', 'Bradyn Kramer', '2017-10-06')
) as t(Id, ClCode, Manager, ChangeDate)
)
, grouped as
(
select c.ClCode
, count(distinct c.Manager) [ManagerChangesCount]
, STRING_AGG(c.[Manager], ',') within group (order by c.MinChangeDate) [Managers]
, STRING_AGG(c.MinChangeDate, ',') within group (order by c.MinChangeDate) [ChangeDates]
from (
select x.ClCode
, x.[Manager]
, min(x.ChangeDate) [MinChangeDate]
from tbl x
group by x.ClCode, x.[Manager]
) c
group by c.ClCode
)
select *
from grouped
我的示例数据集包含有关某些客户机(ClCode)何时(ChangeDate)更改其经理(manager)的数据。它是真正的DWH客户机维度表(SCD类型2)的一部分,因此这些“副本”只包含其他列中某个地方的更改
我想要实现的是:我需要一个客户机代码列表,其中列出了他们的经理被更改的次数,以及一个以逗号分隔的列表,其中列出了按更改顺序从左到右排序的经理姓名
ClCode ManagerChangesCount Managers ChangeDates
000005 6 Cierra Vega,Alden Cantrell,Kierra Gentry,Pierre Cox,Thomas Crane,Miranda Shaffer 2017-10-05,2017-11-29,2018-09-05,2018-11-06,2019-09-11,2020-04-27
000360 1 Bradyn Kramer 2017-10-06
但事实上,我收到的结果没有或有一些奇怪的排序
ClCode ManagerChangesCount Managers ChangeDates
000005 6 Alden Cantrell,Cierra Vega,Kierra Gentry,Miranda Shaffer,Pierre Cox,Thomas Crane 2017-11-29,2017-10-05,2018-09-05,2020-04-27,2018-11-06,2019-09-11
000360 1 Bradyn Kramer 2017-10-06
此查询返回良好的排序:
,则计数(不同的c.Manager)[Manager更改]
其中ClCode='000005'
伙计们,如果你能弄明白这一点,请帮助我理解为什么排序不起作用首先,我同意你得到的行为不应该发生,但是,堆栈溢出不是为了报告应用程序的错误。对于SQL Server,这应该在他们的数据库中完成 至于解决问题,从
计数中删除冗余的DISTINCT
会导致问题消失。要实现DISTINCT
(在选择DISTINCT
或计数(DISTINCT{expression})
中),SQL Server需要首先对结果进行排序,这样就可以轻松删除具有相同排序位置的任何值。因此,排序在STRING\u AGG
表达式中表示,即使它们有一个显式的ORDER BY
子句
我之所以说您的DISTINCT
是多余的,是因为在查询中,对于给定的ClCode
值,将不会有重复的Manager
。这是因为您已经在子查询中的Manager
和ClCode
上分组。如果单独运行该查询,您将看到Manager
没有任何重复项:
WITH tbl AS
(SELECT Id,
ClCode,
Manager,
ChangeDate
FROM (VALUES (1, '000005', 'Cierra Vega', '2017-10-05'),
(2, '000005', 'Alden Cantrell', '2017-11-29'),
(3, '000005', 'Alden Cantrell', '2017-11-30'),
(4, '000005', 'Kierra Gentry', '2018-09-05'),
(5, '000005', 'Kierra Gentry', '2018-09-12'),
(6, '000005', 'Pierre Cox', '2018-11-06'),
(7, '000005', 'Thomas Crane', '2019-09-11'),
(8, '000005', 'Thomas Crane', '2019-10-01'),
(9, '000005', 'Miranda Shaffer', '2020-04-27'),
(10, '000360', 'Bradyn Kramer', '2017-10-06')) t (Id, ClCode, Manager, ChangeDate) )
SELECT x.ClCode,
x.[Manager],
MIN(x.ChangeDate) AS [MinChangeDate]
FROM tbl x
GROUP BY x.ClCode,
x.[Manager];
因此,COUNT
中的DISTINCT
只是增加了实例的开销,因为它不是必需的(SQL Server已经按
对组的数据进行了排序,为什么要求它再次排序?)。如果您在已经聚合的查询中使用了DISTINCT
,那么您很可能不需要它。如果您已经在子查询中按Manager
进行分组,为什么在外部查询的COUNT
中需要DISTINCT
?您已经将该值分组,因此不需要它。删除不同的
,就可以得到想要的结果。使用不同的
将强制进行进一步的排序,这可能会导致问题,但是,报告错误并不如此;使用@Larnu,这个“独特的”出现在创建查询的过程中的某个地方。删除它会使排序“很好”,但无论如何,我无法理解它与字符串\u agg中的排序有什么关系?根据我之前的评论,“使用DISTINCT
将强制进一步排序,这可能会导致问题,@Larnu删除DISTINCT真的很有帮助,你能给出答案吗?我相信这些信息将来会对某人有所帮助