我有以下代码清单
Code Meaning
1 Single
2 Married/Separate
3 Divorced
4 Widowed
8 Not Applicable
99 Not known
我正在尝试使用CTE将这些展平为一行。我有一个使用RowNumber函数的CTE解决方案。
WITH Flattened (JoinItem, CodeMeaning) AS
(
SELECT 1 AS JoinItem, CAST('' AS VARCHAR(255))
UNION ALL
SELECT f.JoinItem+1, CAST(f.CodeMeaning + ',' + c.CodeMeaning AS VARCHAR(255))
FROM
(
SELECT JoinItem = ROW_NUMBER() OVER (ORDER BY Code),c.Code + ' - ' + c.Meaning AS CodeMeaning
FROM Codes c
) c
INNER JOIN Flattened f
ON f.JoinItem=c.JoinItem
)
SELECT TOP 1 JoinItem, CodeMeaning
FROM Flattened
ORDER BY JoinItem DESC
但是,我想知道我是否可以在不使用RowNumber功能但仍然使用CTE的情况下执行此操作。所以我有以下内容 - 我认为更简单 - Sql
WITH Flattened (JoinItem, CodeMeaning) AS
(
SELECT 1 AS JoinItem, CAST('' AS VARCHAR(255))
UNION ALL
SELECT c.JoinItem, CAST(f.CodeMeaning + ',' + c.CodeMeaning AS VARCHAR(255))
FROM
(
SELECT 1 AS JoinItem,c.Code + ' - ' + c.Meaning AS CodeMeaning
FROM Codes c
) c
INNER JOIN Flattened f
ON f.JoinItem=c.JoinItem
)
SELECT JoinItem, odeMeaning
FROM Flattened
现在它正在最大化递归并产生类似于笛卡尔联合的东西 - 如果不是更糟糕的话!
我希望每次使用固定的" JoinItem"
尝试让它加入到锚记录中因此,如果有解决方案,任何指向我错误的地方都会有所帮助。
答案 0 :(得分:5)
假设这是SQL Server,您是否考虑过这样的事情:
select stuff((select ',' + c.code + '-' + c.Meaning
from codes c
order by code
for xml path ('')
), 1, 1, '')
编辑:
要使用CTE执行此操作,请先定义序列号 ,然后执行展平:
with c as (
select row_number() over (order by code) as seqnum, c.code + '-' + c.meaning as CodeMeaning
from codes c
),
flattened as (
select CodeMeaning as CodeMeaning
from c
where rownum = 1
union all
select f.CodeMeaning + ',' + c.CodeMeaning
from c join
flattened f
on c.seqnum = f.seqnum + 1
)
select *
from flattened;
如果列表太长,则可能必须增加默认递归级别。
答案 1 :(得分:0)
如果没有ROW_NUMBER(),您的查询应该是
random_state
您也可以在最后一个选择中使用ORDER BY LEN(CodeMeaning)DESC。在这种情况下,lev(递归级别)列不是必需的。 如果您对代码值有额外的了解,那么您可以使用更准确的INNER JOIN谓词来优化查询,例如ON f.Code< c.Code AND f.Code + 10> c.Code。