我需要在执行GROUP BY时找出值来自的行ID。
首先创建并填充“播放对象”
-- vertical coalesce with row-source of value :) instead of column-source of value as in horizontal coalesce :)
CREATE TABLE #TBL(ID INT, GR INT, A INT, B INT)
INSERT INTO #TBL
SELECT 1,1,1,NULL
UNION ALL SELECT 2,1,NULL,2
UNION ALL SELECT 3,1,NULL,3
UNION ALL SELECT 4,2,2,NULL
UNION ALL SELECT 5,2,NULL,NULL
UNION ALL SELECT 6,2,6,NULL
选择最小值很简单:
SELECT GR, MIN(A) A, MIN(B) B,
'Which first available row did A come from?' A_ID,
'Which first available row did B come from?' B_ID
FROM #TBL
GROUP BY GR
但回答问题不是!
我尝试过子查询,但由于值来自不同的行,因此不起作用:
SELECT a.*
from #TBL a
join (
SELECT GR, MIN(A) A, MIN(B) B,
'Which row did A come from?' A_ID,
'Which row did B come from?' B_ID
FROM #TBL
GROUP BY GR) b on a.GR = b.GR and a.A = b.A and a.B = b.B
--DROP TABLE #TBL
请帮忙。
答案 0 :(得分:2)
我不确定它是否会执行连接/外部应用(我认为它会),但这将有效:
WITH CTE AS
( SELECT GR,
A,
B,
ID,
MinA = MIN(A) OVER(PARTITION BY GR),
MinB = MIN(B) OVER(PARTITION BY GR)
FROM #TBL
)
SELECT GR,
A = MIN(A),
B = MIN(B),
A_ID = MIN(CASE WHEN MinA = A THEN ID END),
B_ID = MIN(CASE WHEN MinB = B THEN ID END)
FROM CTE
GROUP BY GR;
在这个小样本上,统计数据表明这一点表现更好:
使用聚合
(估计)查询成本13%
表'工作台'。扫描计数3,逻辑读取21,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。
使用外部申请
(估计)查询成本87%
表'工作台'。扫描计数16,逻辑读取42,物理读取0,预读取读取0,lob逻辑读取0,lob物理读取0,lob预读读取0。
但是你可能会发现索引的真实例子会有所不同。
答案 1 :(得分:1)
这应该做:
SELECT DISTINCT
T1.GR,
T2.A,
T3.B,
T2.ID A_ID,
T3.ID B_ID
FROM #TBL T1
OUTER APPLY (SELECT TOP 1 *
FROM #TBL
WHERE GR = T1.GR
AND A IS NOT NULL
ORDER BY A, ID) T2
OUTER APPLY (SELECT TOP 1 *
FROM #TBL
WHERE GR = T1.GR
AND B IS NOT NULL
ORDER BY B, ID) T3
结果:
╔════╦═══╦══════╦══════╦══════╗
║ GR ║ A ║ B ║ A_ID ║ B_ID ║
╠════╬═══╬══════╬══════╬══════╣
║ 1 ║ 1 ║ 2 ║ 1 ║ 2 ║
║ 2 ║ 2 ║ NULL ║ 4 ║ NULL ║
╚════╩═══╩══════╩══════╩══════╝
答案 2 :(得分:0)
;WITH CTEA AS
( SELECT ID, GR, A, ROW_NUMBER() OVER(PARTITION BY GR ORDER BY A) AS 'RowNum'
FROM #TBL where A is not null
), CTEB AS
( SELECT ID, GR, B, ROW_NUMBER() OVER(PARTITION BY GR ORDER BY B) AS 'RowNum'
FROM #TBL where B is not null
)
select CTEA.GR, CTEA.A, CTEA.ID, CTEB.B, CTEB.ID
from CTEA
jull outer join CTEB
on CTEA.GR = CTEB.GR
and CTEA.RowNum = 1
and CTEB.RowNum = 1