我必须在每一列中找到第一个匹配,在一行tsql中需要(没有循环或游标 - 在光标回答后添加 - )
;WITH TempTable AS
(
SELECT * FROM (VALUES (1,1),(2,2),(2,3),(3,2),(3,3),
(4,2),(4,3),(5,4)) AS y(pos,MatchingPos)
)
SELECT * FROM TempTable...
结果:
1,1 returned
2,2 returned
2,3 Not returned: Column 1 Value 2 already returned
3,2 Not returned: Column 2 Value 2 already returned
3,3 returned
4,2 Not returned: Column 2 Value 2 already returned
4,3 Not returned: Column 2 Value 3 already returned
5,4 returned
答案 0 :(得分:0)
我不是游标的忠实粉丝。但这似乎是必要的:
Declare @t table(pos int,MatchingPos int)
Declare @pos int, @MatchingPos int
Declare SqlCursor CURSOR FAST_FORWARD FOR
SELECT pos,MatchingPos FROM
(VALUES (1,1),(2,2),(2,3),(3,2),(3,3),
(4,2),(4,3),(5,4)) AS y(pos,MatchingPos)
OPEN SqlCursor
FETCH NEXT FROM SqlCursor
INTO @pos, @MatchingPos
WHILE @@FETCH_STATUS = 0
BEGIN
insert @t
select @pos, @MatchingPos
where not exists
(select 1 from @t where pos = @pos or @MatchingPos = MatchingPos)
FETCH NEXT FROM SqlCursor
INTO @pos, @MatchingPos
END
CLOSE SqlCursor
DEALLOCATE SqlCursor
select * from @t
结果:
pos MatchingPos
1 1
2 2
3 3
5 4
答案 1 :(得分:0)
好吧 - 这个CTE似乎适用于上面的数据集。它有点乱,CTE可以根据你的数据合理地轻松地进行最大递归。
;WITH TempTable AS
(
SELECT * FROM (VALUES (1,1),(2,2),(2,3),(3,2),(3,3),
(4,2),(4,3),(5,4)) AS y(pos,MatchingPos)
), TempTable2 AS
(
SELECT T1.pos,
T1.MatchingPos,
CASE WHEN min(T2.MatchingPos) < T1.MatchingPos THEN 1 ELSE 0 END as Pos_Exists,
CASE WHEN min(T3.pos) < T1.pos THEN 1 ELSE 0 END as MatchingPos_Exists,
ROW_NUMBER() OVER(ORDER BY T1.pos ASC, T1.MatchingPos ASC) RowNum
FROM TempTable T1
LEFT JOIN TempTable T2
ON T1.pos = T2.pos AND T1.MatchingPos != T2.MatchingPos
LEFT JOIN TempTable T3
ON T1.MatchingPos = T3.MatchingPos AND T1.pos != T3.pos
GROUP BY T1.pos, T1.MatchingPos
)
, TempTable3 AS
(
SELECT pos, MatchingPos, RowNum, 1 AS Included, CAST(0 aS BIGINT) ParentRow
FROM TempTable2
WHERE Pos_Exists = 0 AND MatchingPos_Exists = 0
UNION ALL
SELECT T1.pos, T1.MatchingPos, T1.RowNum,
T2.Included - 1 AS Included,
CASE WHEN T2.Included = 1 THEN T2.RowNum WHEN T2.Included < 0 THEN T2.RowNum ELSE -1 END as ParentRow
FROM TempTable2 T1
JOIN TempTable3 T2
ON T1.RowNum > T2.RowNum
AND (T1.pos = T2.pos OR T1.MatchingPos = T2.MatchingPos)
AND (T2.ParentRow != 0 OR T2.Included = 1)
)
SELECT pos, MatchingPos FROM TempTable3
GROUP BY pos, MatchingPos
HAVING MAX(Included) = 1 OR (MAX(ParentRow) = -1)