我有一个包含项目设置代码的表格。每个代码组由group_id
定义。该表定义如下:
CREATE TABLE item_code (
id int PRIMARY KEY NOT NULL IDENTITY (1,1),
item_id int DEFAULT NULL,
group_id int NOT NULL,
code varchar(50) NOT NULL
);
CREATE TABLE groups (
id int PRIMARY KEY NOT NULL IDENTITY (1,1),
name varchar(50) NOT NULL,
order int NOT NULL
)
对于表格中的每个item_id
,我需要从论坛code
订购的每个group_id
中选择1 order
。例如:
INSERT INTO groups (id, name, order) VALUES (1, 'one', 10), (2, 'two', 20), (3, 'three', 30);
INSERT INTO item_code (item_id, group_id, [code])
VALUES
(99, 1, 'code1-1'),
(99, 1, 'code1-2'),
(99, 2, 'code2-1'),
(99, 2, 'code2-2'),
(99, 3, 'code3-1'),
(100,1, 'another-code');
将导致设置:
item_id code_combination
99 "code1-1"
99 "code1-2"
99 "code2-1"
99 "code2-2"
99 "code3-1"
99 "code1-1, code2-1"
99 "code1-1, code2-2"
99 "code1-2, code2-1"
99 "code1-2, code2-2"
99 "code1-1, code3-1"
99 "code1-2, code3-1"
99 "code2-1, code3-1"
99 "code2-2, code3-1"
99 "code1-1, code2-1, code3-1"
99 "code1-2, code2-1, code3-1"
99 "code1-1, code2-2, code3-1"
99 "code1-2, code2-2, code3-1"
100 "another-code"
实际结果的顺序无关紧要。我为item_id
== 100添加了一行,只是为了显示所有item_id的结果都应该包含在内。
到目前为止我做了什么: 我已经构建了一个获取代码组合的CTE,但它不尊重item_id,群组或订单以及我遇到的问题:
;WITH cte ( combination, curr ) AS (
SELECT CAST(ic.code AS VARCHAR(MAX)), ic.id
FROM items_code ic
UNION ALL
SELECT CAST( c.combination + ',' + CAST(ic.code AS VARCHAR(10) ) AS VARCHAR(MAX) ), ic.id
FROM item_code ic
INNER JOIN
cte c
ON ( c.curr < ic.id )
)
SELECT combination FROM cte
更新:我的架构比我最初发布的稍微复杂一些,并在this fiddle中构建了架构。这个想法是一样的,只是&#34; order&#34;在另一张桌子上定义。
答案 0 :(得分:1)
在递归cte中添加更多内容,扩展最终连接条件以及一些其他列:
;with cte as (
select
ic.id
, ic.item_id
, ic.group_id
, g.[order]
, level = 0
, combination = cast(ic.code as varchar(max))
from item_code ic
inner join groups g
on ic.group_id = g.id
union all
select
ic.id
, ic.item_id
, ic.group_id
, g.[order]
, level = c.level + 1
, combination = cast( c.combination + ',' + cast(ic.code as varchar(10) ) as varchar(max) )
from item_code ic
inner join groups g
on ic.group_id = g.id
inner join cte c
on c.id < ic.id
and c.[order] < g.[order]
and c.item_id = ic.item_id
)
select *
from cte
order by item_id, level, combination
rextester演示:http://rextester.com/PJC44281
返回:
+----+---------+----------+-------+-------+-------------------------+
| id | item_id | group_id | order | level | combination |
+----+---------+----------+-------+-------+-------------------------+
| 1 | 99 | 1 | 10 | 0 | code1-1 |
| 2 | 99 | 1 | 10 | 0 | code1-2 |
| 3 | 99 | 2 | 20 | 0 | code2-1 |
| 4 | 99 | 2 | 20 | 0 | code2-2 |
| 5 | 99 | 3 | 30 | 0 | code3-1 |
| 3 | 99 | 2 | 20 | 1 | code1-1,code2-1 |
| 4 | 99 | 2 | 20 | 1 | code1-1,code2-2 |
| 5 | 99 | 3 | 30 | 1 | code1-1,code3-1 |
| 3 | 99 | 2 | 20 | 1 | code1-2,code2-1 |
| 4 | 99 | 2 | 20 | 1 | code1-2,code2-2 |
| 5 | 99 | 3 | 30 | 1 | code1-2,code3-1 |
| 5 | 99 | 3 | 30 | 1 | code2-1,code3-1 |
| 5 | 99 | 3 | 30 | 1 | code2-2,code3-1 |
| 5 | 99 | 3 | 30 | 2 | code1-1,code2-1,code3-1 |
| 5 | 99 | 3 | 30 | 2 | code1-1,code2-2,code3-1 |
| 5 | 99 | 3 | 30 | 2 | code1-2,code2-1,code3-1 |
| 5 | 99 | 3 | 30 | 2 | code1-2,code2-2,code3-1 |
| 6 | 100 | 1 | 10 | 0 | another-code |
+----+---------+----------+-------+-------+-------------------------+