将列值聚合到列表中会产生错误
Aggregate column values into a list produces an error
以下查询
DECLARE @SNH TABLE
(
dt date,
QueueName varchar(10),
SN varchar(10)
)
INSERT INTO @SNH (Dt, QueueName, SN)
VALUES ('2001-04-04', 'Queue01', 'Q01SN01'),
('2001-04-05', 'Queue01', 'Q01SN01'),
('2001-04-06', 'Queue01', 'Q01SN01'),
('2001-04-04', 'Queue02', 'Q02SN01'),
('2001-04-05', 'Queue02', 'Q02SN01'),
('2001-04-06', 'Queue02', 'Q02SN02')
DECLARE @QH TABLE
(
DT date,
QueueName varchar(10)
)
INSERT INTO @QH(DT, QueueName)
VALUES ('2001-04-04','Queue01'),
('2001-04-05','Queue01'),
('2001-04-06','Queue01'),
('2001-04-04','Queue02'),
('2001-04-05','Queue02'),
('2001-04-06','Queue02')
SELECT DISTINCT
q.QueueName clnQueueName,
MIN(q.Dt) OVER (PARTITION BY q.QueueName) clnStartDate,
MAX(q.Dt) OVER (PARTITION BY q.QueueName) clnEndDate,
s.SN
FROM
@QH q
LEFT JOIN
@SNH s ON s.QueueName = q.QueueName
returns 这个输出:
clnQueueName
clnStartDate
clnEndDate
SN
Queue01
2001-04-04
2001-04-06
Q01SN01
Queue02
2001-04-04
2001-04-06
Q02SN01
Queue02
2001-04-04
2001-04-06
Q02SN02
我的目标是用
聚合成逗号分隔的列表
SELECT DISTINCT
q.QueueName clnQueueName,
MIN(q.Dt) OVER (PARTITION BY q.QueueName) clnStartDate,
MAX(q.Dt) OVER (PARTITION BY q.QueueName) clnEndDate,
STRING_AGG(s.SN,',')
FROM
@QH q
LEFT JOIN
@SNH s ON s.QueueName = q.QueueName AND s.Dt = q.Dt
如下
clnQueueName
clnStartDate
clnEndDate
SN
Queue01
2001-04-04
2001-04-06
Q01SN01
Queue02
2001-04-04
2001-04-06
Q02SN01,Q02SN02
相反,我得到:
Msg 8120, Level 16, State 1, Line 36
Column '@QH.QueueName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
抱歉,我听不懂。
@QH.QueueName
甚至没有在SELECT
中提到,只有q.QueueName
.
我在这里缺少什么?
根据 the docs,如果 string_agg
不是唯一选择的项目,则需要 group by
子句。正确分组后,您不再需要 window 函数或 distinct
.
要仅获取 SN
的不同值,您需要分组两次,第一次在 sub-query 中(在本例中为 CTE)以获得 SN
的不同值,并且第二次使用 string_agg
以获得 QueueName
.
的不同值
WITH cte AS (
SELECT
q.QueueName clnQueueName
, MIN(q.Dt) clnStartDate
, MAX(q.Dt) clnEndDate
, s.SN
FROM @QH q
LEFT JOIN @SNH s
ON s.QueueName = q.QueueName AND s.Dt = q.Dt
GROUP BY q.QueueName, s.SN
)
SELECT clnQueueName
, MIN(clnStartDate) clnStartDate
, MAX(clnEndDate) clnEndDate
, STRING_AGG(SN,',') SN
FROM cte
GROUP BY clnQueueName;
Returns:
clnQueueName
clnStartDate
clnEndDate
SN
Queue01
2001-04-04
2001-04-06
Q01SN01
Queue02
2001-04-04
2001-04-06
Q02SN01,Q02SN02
以下查询
DECLARE @SNH TABLE
(
dt date,
QueueName varchar(10),
SN varchar(10)
)
INSERT INTO @SNH (Dt, QueueName, SN)
VALUES ('2001-04-04', 'Queue01', 'Q01SN01'),
('2001-04-05', 'Queue01', 'Q01SN01'),
('2001-04-06', 'Queue01', 'Q01SN01'),
('2001-04-04', 'Queue02', 'Q02SN01'),
('2001-04-05', 'Queue02', 'Q02SN01'),
('2001-04-06', 'Queue02', 'Q02SN02')
DECLARE @QH TABLE
(
DT date,
QueueName varchar(10)
)
INSERT INTO @QH(DT, QueueName)
VALUES ('2001-04-04','Queue01'),
('2001-04-05','Queue01'),
('2001-04-06','Queue01'),
('2001-04-04','Queue02'),
('2001-04-05','Queue02'),
('2001-04-06','Queue02')
SELECT DISTINCT
q.QueueName clnQueueName,
MIN(q.Dt) OVER (PARTITION BY q.QueueName) clnStartDate,
MAX(q.Dt) OVER (PARTITION BY q.QueueName) clnEndDate,
s.SN
FROM
@QH q
LEFT JOIN
@SNH s ON s.QueueName = q.QueueName
returns 这个输出:
clnQueueName | clnStartDate | clnEndDate | SN |
Queue01 | 2001-04-04 | 2001-04-06 | Q01SN01 |
Queue02 | 2001-04-04 | 2001-04-06 | Q02SN01 |
Queue02 | 2001-04-04 | 2001-04-06 | Q02SN02 |
我的目标是用
聚合成逗号分隔的列表SELECT DISTINCT
q.QueueName clnQueueName,
MIN(q.Dt) OVER (PARTITION BY q.QueueName) clnStartDate,
MAX(q.Dt) OVER (PARTITION BY q.QueueName) clnEndDate,
STRING_AGG(s.SN,',')
FROM
@QH q
LEFT JOIN
@SNH s ON s.QueueName = q.QueueName AND s.Dt = q.Dt
如下
clnQueueName | clnStartDate | clnEndDate | SN |
Queue01 | 2001-04-04 | 2001-04-06 | Q01SN01 |
Queue02 | 2001-04-04 | 2001-04-06 | Q02SN01,Q02SN02 |
相反,我得到:
Msg 8120, Level 16, State 1, Line 36
Column '@QH.QueueName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause
抱歉,我听不懂。
@QH.QueueName
甚至没有在SELECT
中提到,只有q.QueueName
.
我在这里缺少什么?
根据 the docs,如果 string_agg
不是唯一选择的项目,则需要 group by
子句。正确分组后,您不再需要 window 函数或 distinct
.
要仅获取 SN
的不同值,您需要分组两次,第一次在 sub-query 中(在本例中为 CTE)以获得 SN
的不同值,并且第二次使用 string_agg
以获得 QueueName
.
WITH cte AS (
SELECT
q.QueueName clnQueueName
, MIN(q.Dt) clnStartDate
, MAX(q.Dt) clnEndDate
, s.SN
FROM @QH q
LEFT JOIN @SNH s
ON s.QueueName = q.QueueName AND s.Dt = q.Dt
GROUP BY q.QueueName, s.SN
)
SELECT clnQueueName
, MIN(clnStartDate) clnStartDate
, MAX(clnEndDate) clnEndDate
, STRING_AGG(SN,',') SN
FROM cte
GROUP BY clnQueueName;
Returns:
clnQueueName | clnStartDate | clnEndDate | SN |
---|---|---|---|
Queue01 | 2001-04-04 | 2001-04-06 | Q01SN01 |
Queue02 | 2001-04-04 | 2001-04-06 | Q02SN01,Q02SN02 |