我需要从表中的一列返回所有值的组合。结果应排序。
----------------------
Table A
----------------------
ID TEXT
----------------------
100 AAA
100 BBB
100 CCC
200 DDD
200 EEE
预期结果:
100 /AAA
100 /BBB
100 /CCC
100 /AAA/BBB
100 /AAA/CCC
100 /BBB/CCC
100 /AAA/BBB/CCC
200 /DDD
200 /EEE
200 /DDD/EEE
产生的select语句应该能够成为另一个select的一部分。
我已经尝试过了,它似乎正在工作,但是我不能将其用作子查询。
WITH cte ( combination, curr ) AS (
SELECT CAST( t.COL AS VARCHAR(80) ),
t.COL
FROM TABLE_A t
UNION ALL
SELECT CAST( c.combination + '/' + CAST( t.COL AS VARCHAR(3) ) AS VARCHAR(80) ), t.COL
FROM TABLE_A t
INNER JOIN
cte c
ON ( c.curr < t.COL )
)
SELECT '/' + combination FROM cte
答案 0 :(得分:1)
您可以为此使用recursive CTE。问题是您缺少正确连接下一个值的行号(而从未与前一个值连接)。我想这就是您想要的,因为您在结果中包括了路径/AAA/BBB
但没有包括/BBB/AAA
,因此AAA
的记录必须与BBB
联接,但记录与{{1} }不能与BBB
一起使用,因此需要一种数据中不存在的特定排序方法。
我用AAA
模拟了一个行号,您可以将IDENTITY
与所需的任何ROW_NUMBER()
一起使用。
设置:
OVER(PARTITION BY ID ORDER BY <expression or column> )
解决方案:
IF OBJECT_ID('tempdb..#Values') IS NOT NULL
DROP TABLE #Values
CREATE TABLE #Values(
RowID INT IDENTITY,
ID INT,
Text VARCHAR(100))
INSERT INTO #Values (
ID,
Text)
VALUES
(100, 'AAA'),
(100, 'BBB'),
(100, 'CCC'),
(200, 'DDD'),
(200, 'EEE')
结果:
;WITH RecursiveJoins AS
(
-- Anchor (original row)
SELECT
OriginRowID = V.RowID,
CurrentRowID = V.RowID,
ID = V.ID,
Path = CONVERT(VARCHAR(MAX), '/' + V.Text),
RecursionLevel = 0
FROM
#Values AS V
UNION ALL
-- Recursion (add any value with the same ID and higher RowID)
SELECT
OriginRowID = R.OriginRowID,
CurrentRowID = V.RowID,
ID = R.ID,
Path = R.Path + '/' + V.Text,
RecursionLevel = R.RecursionLevel + 1
FROM
RecursiveJoins AS R
INNER JOIN #Values AS V ON
R.ID = V.ID AND
R.CurrentRowID < V.RowID
)
SELECT
R.ID,
R.Path,
R.RecursionLevel
FROM
RecursiveJoins AS R
ORDER BY
R.ID,
R.RecursionLevel,
R.Path
答案 1 :(得分:0)
在这里,下面的查询将为您提供预期的输出:
在此处创建临时表以执行该操作:
select * into #tt from (
select '100' as ID,'AAA' as TEXT
union all
select '100' as ID,'BBB' as TEXT
union all
select '100' as ID,'CCC' as TEXT
union all
select '200' as ID,'DDD' as TEXT
union all
select '200' as ID,'EEE' as TEXT
)a
select * from #tt
GO
从这里开始您的实际问题解决方案:
WITH cte ( ID,Val, curr ) AS (
SELECT t.ID,CAST( t.[TEXT] AS VARCHAR(max) ),
t.[TEXT]
FROM #tt t
where t.id = 100
UNION ALL
SELECT t.ID, CAST( c.Val + '/' + CAST( t.[TEXT] AS VARCHAR(max) ) AS VARCHAR(max) ),
t.[TEXT]
FROM #tt t
INNER JOIN
cte c
ON ( c.curr < t.[TEXT] )
where t.id = 100
)
,cte2 ( ID,Val, curr ) AS (
SELECT t.ID,CAST( t.[TEXT] AS VARCHAR(max) ),
t.[TEXT]
FROM #tt t
where t.id = 200
UNION ALL
SELECT t.ID, CAST( c.Val + '/' + CAST( t.[TEXT] AS VARCHAR(max) ) AS VARCHAR(max)
),
t.[TEXT]
FROM #tt t
INNER JOIN
cte2 c
ON ( c.curr < t.[TEXT] )
where t.id = 200
)
SELECT ID,concat('/',Val)
FROM cte
union all
SELECT ID,concat('/',Val)
FROM cte2
order by 1