我目前正在刷新我的SQL知识,并在以下查询中遇到一些困难。
要求是:
对于每个制造商,按字母顺序列出" /"作为他所生产的所有类型产品的分界。
演绎:制造商,产品类型'列表
以下解决方案确实有效,但我并不完全理解......
;with
t1 as
(select maker, type, DENSE_RANK() over(partition by maker order by type) rn
from product
),
tr(maker, type,lev) as
(select distinct t1.maker, cast(t1.type as nvarchar) , 2 from t1 where t1.rn = 1
union all
select t1.maker, cast(tr.type +'/'+t1.type as nvarchar), lev + 1
from t1 join tr on (t1.maker = tr.maker and t1.rn = tr.lev
)
)
select maker, max(type) names from tr group by maker
这些输出:
1 | A | Laptop/PC/Printer
2 | B | Laptop/PC
3 | C | Laptop
4 | D | Printer
5 | E | PC/Printer
*第二列是制造商,第三列是动态连接的类型列表。
现在,我对lev究竟是如何动态增长感到有些困惑。我在这里缺少某种循环吗? 为什么从2开始? 如果没有"演员"?
,它为什么不起作用如果有人能够解释这个问题背后的逻辑,我将非常感激。
非常感谢!
答案 0 :(得分:0)
你正在看的是一个递归的CTE,一个自称的CTE。它是你认为的循环"影响。当我第一次看到它时,递归会在我的大脑中产生扭结。它有助于查看一些示例并尝试创建一些您自己的简单示例。我仍然不是最好的,但我变得更好。我在你的代码中添加了一些注释。希望这会有所帮助。
;WITH t1
AS (
SELECT maker,
type,
--Partition says each maker is a group so restart at 1
--Order by type is alphabetic
--DENSE_RANK() means if there are two the of the same item, they get the same number
DENSE_RANK() OVER (PARTITION BY maker ORDER BY type) rn
FROM product
),
--This is a recursive CTE meaning a CTE that calls itself(what is doing the "looping"
tr (maker,type,lev)
AS (
--Grab only the distinct items from your ranked table
SELECT DISTINCT t1.maker,
cast(t1.type AS NVARCHAR),
2 --This is the start of your recursive loop
FROM t1
WHERE t1.rn = 1
UNION ALL
--Recursively loop through you data, adding each string at the end with the '/'
SELECT t1.maker,
cast(tr.type + '/' + t1.type AS NVARCHAR),
--Plus one to grab the next value
lev + 1
FROM t1
INNER JOIN tr ON (
--Only match the same makers
t1.maker = tr.maker
--Match to the next value
AND t1.rn = tr.lev
)
)
--I think you know what this does
SELECT maker,
max(type) names
FROM tr
GROUP BY maker