2017-08-22 18 views
1

アイテムのセットコードで構成されるテーブルがあります。各コードのグループはgroup_idで定義されています。次のように表が定義されています。各item_idに対してN値の順序付けられたセットの順列を取得する

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 
) 

の表に、私はグループのorder順各group_idから1 codeを選択する必要があります。たとえば:

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 

UPDATE:私は最初に投稿したものよりも少し複雑なスキーマを持ち、this fiddleにスキーマを構築しました。考え方は同じですが、それは単に "順序"が別のテーブルで定義されていることです。

;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

リターン:あなたの再帰CTE、最終結合条件を拡大するだけでなく、いくつかの追加の列にもう少し追加

+0

を私はあなたは何を得ているのか理解していませんが、テーブルのFK参照がなく、グループテーブルのIDプロパティを使用しています。これはアイテムと一致しません表。 – scsimon

答えて

1

+----+---------+----------+-------+-------+-------------------------+ 
| 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   | 
+----+---------+----------+-------+-------+-------------------------+ 
+0

ご協力ありがとうございます。私がこの質問を初めて書いたとき、私はスキーマを単純化しようとしましたが、あなたの答えを私の実際のスキーマに翻訳するのが難しいので、私は自分自身を不自由にしているかもしれません。あなたが気にしないなら、私は実際のスキーマを示すSQLFiddleを作成しました。それは製品間およびグループ内でコードを混在させているようです: http://sqlfiddle.com/#!6/8e52d/ 4/0 – Thelonias

+0

あまりありません。私はjoinの制約を 'item_group'に変更しました。私は近づいています。しかし、私は何も "レベル1"、つまり、3つのコードの組み合わせを取得することはできません。 http://sqlfiddle.com/#!6/8e52d/16/0 – Thelonias

+1

@Thelonias [sqlfiddle.com/#!6/8e52d/25](http://sqlfiddle.com/#!6/8e52d/25)私はこれがあなたが探しているものだと思います。お知らせ下さい。 – SqlZim

関連する問題