我有一张看起来像这样的表,其中以旧值和新值(刚变成的值)显示id。
IF OBJECT_ID('tempdb.dbo.#TT','U')IS NOT NULL
DROP TABLE #TT;
SELECT *
INTO #TT
FROM (
SELECT 1 AS ID, 'A' AS OldValue, 'B' AS NewValue, CONVERT(DATE,'20190421') AS [Date]
UNION ALL
SELECT 1 AS ID, 'B' AS OldValue, 'C' AS NewValue, CONVERT(DATE,'20190423') AS [Date]
UNION ALL
SELECT 2 AS ID, 'D' AS OldValue, 'E' AS NewValue, CONVERT(DATE,'20190422') AS [Date]
UNION ALL
SELECT 3 AS ID, 'J' AS OldValue, 'K' AS NewValue, CONVERT(DATE,'20190422') AS [Date]
UNION ALL
SELECT 3 AS ID, 'K' AS OldValue, 'L' AS NewValue, CONVERT(DATE,'20190423') AS [Date]
UNION ALL
SELECT 3 AS ID, 'L' AS OldValue, 'M' AS NewValue, CONVERT(DATE,'20190424') AS [Date]
) T
;
我想显示每个id和旧值以及最新的值。例如ID = 1和OldValue = A应该显示C或ID = 3并且OldValue = K应该显示M
我试图按如下方式进行递归cte:
WITH RecCTE AS (
SELECT ID, OldValue, NewValue
FROM #TT
UNION ALL
SELECT A.ID, B.OldValue, A.NewValue
FROM #TT A
INNER JOIN RecCTE B ON A.ID = B.ID AND B.NewValue = A.OldValue
)
SELECT *
FROM RecCTE
使用该递归查询。我正确地获得了一些线条,但中间也得到了额外的线条:
| ID | OldValue | NewValue |
|-----------|---------------|----------------|
| 1 | A | B |
| 1 | B | C |
| 2 | D | E |
| 3 | J | K |
| 3 | K | L |
| 3 | L | M |
| 3 | K | M |
| 3 | J | L |
| 3 | J | M |
| 1 | A | C |
我想要这样的结果:
| ID | OldValue | NewValue |
|-----------|---------------|----------------|
| 1 | A | C |
| 1 | B | C |
| 2 | D | E |
| 3 | J | M |
| 3 | K | M |
| 3 | L | M |
答案 0 :(得分:0)
我认为走最后一行应该可以:
WITH RecCTE AS (
SELECT ID, OldValue, NewValue, 1 as lev
FROM #TT
UNION ALL
SELECT A.ID, B.OldValue, A.NewValue, lev + 1
FROM #TT A JOIN
RecCTE B
ON A.ID = B.ID AND B.NewValue = A.OldValue
)
SELECT *
FROM (SELECT r.*, ROW_NUMBER() OVER (PARTITION BY id, OldValue ORDER BY lev DESC) as seqnum
FROM RecCTE r
) r
WHERE seqnum = 1;
答案 1 :(得分:0)
如果数据按我认为的方式工作,那么下面的代码将不使用递归进行操作:
auto1