2016-03-29 8 views
0

私は次のクエリを持っています。プロダクトIDを入力(2,4,5)とすると、私はそのリストに関連するkeyidを取得したい。それから私はそのキーIDに関連するすべての製品を取得したい。単一のSQLクエリ(依存結果)でCTEとSELECTを置き換えることは可能ですか

例:私はproductidを2,4,5として私のsprocへの入力として渡していますが、私は22,34,35,38(CTEの結果)としてkeyidを取得します。このキーは入力プロダクトリストにマッピングされます。このキー(CTEの結果)に基づいて、私はすべての製品がこのキーに関連付けられます。 keyid = 22に商品IDが2,4,5,8,9 &、keyid = 34などの商品名が2,4,5,23,45などの商品を持つようになりました。

上記の問題に対する以下の解決策。私はちょうど2つのテーブルが繰り返されているので、何とかこの解決法を改善することができるか、または単一のクエリでこの仕事を行うことができるかどうかを期待しています。

製品とproductkeymappingテーブルの
WITH GetKey_CTE 
AS 
(
    SELECT k.id, some other select statements 
    FROM KeyDim k 
     INNER JOIN KeyData kd on kd.id = k.id 
     INNER JOIN KeyProductMapping kpm on kpm.id = k.id and kpm.mkey = k.mkey 
     INNER JOIN Products p on p.productid = kpm.productid 
         and p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
    WHERE clause conditions 
) 

SELECT cte.id as keyid, pn.productname, some other columns 
FROM GetKey_CTE cte 
INNER JOIN KeyProductMapping kpm on cte.id = kpm.id 
INNER JOIN Products pn on pn.productid = kpm.productid 
ORDER BY cte.id 

データセット例:

Productsテーブルの場合:

productid name 
1   car 
2   bike 
3   plane 
4   bus 
5   train 
45  cycle 

ProductKeyMappingテーブル

productid keyid 
1    23 
2    987 
45   23 
1    56 

入力商品コードが1であると言う、最終的な結果はであるべきです:

keyid productid name 
23  1   car 
23  45   cycle 
56  1   car 
+0

を見ているメインのステートメントに、我々があれば言うことができないことを移動'KeyProductsMapping'と' Products'テーブルへの2つの参照を避けることが可能です。 (共通のテーブル式は厳密には必要ではありません。同じクエリがインラインビューとして表示され、cte(またはインラインビュー)クエリにGROUP BYが含まれていないと仮定すると、別のSELECT。クエリが単一のSELECTで書き直される可能性がありますが、そのクエリは同じテーブル参照を持ちます... 'Products'と' KeyProductsMapping'テーブルへの2つの参照 – spencer7593

+0

私には意味がありません:INNER JOIN Products pn on cte.productid = kpm.productid – Paparazzi

+0

mymistake、私はそれを更新します、関係はマッピングテーブル – user2406618

答えて

0

また、あなたは以下のようなインライン・ビューとのCTEを交換するが、あなたは再びJOINS複製されている理由を確認することができます注意してサブクエリ

SELECT * FROM KeyProductMapping km 
INNER JOIN 
(
SELECT k.id, some other select statements 
    FROM KeyDim k 
     INNER JOIN KeyData kd ON kd.id = k.id 
     INNER JOIN KeyProductMapping kpm ON kpm.id = k.id AND kpm.mkey = k.mkey 
     INNER JOIN Products p ON p.productid = kpm.productid 
         AND p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
    WHERE clause conditions) AS p ON p.id = km.id 
INNER JOIN Products pn ON p.productid = km.productid 
ORDER BY cte.id 
0

を使用して行うことができます。あなたはさらに見えるように、あなたの望む結果と一緒にいくつかのサンプルデータを投稿できますか?あなたがオンラインでCTE(サブクエリ)

多くのものを照会

あなたの上
SELECT cte.id AS keyid, pn.productname, some other columns 
FROM (
    SELECT k.id, some other select statements 
    FROM KeyDim k 
     INNER JOIN KeyData kd ON kd.id = k.id 
     INNER JOIN KeyProductMapping kpm ON kpm.id = k.id AND kpm.mkey = k.mkey 
     INNER JOIN Products p ON p.productid = kpm.productid 
         AND p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
    WHERE clause conditions) cte 
INNER JOIN KeyProductMapping kpm ON cte.id = kpm.id 
INNER JOIN Products pn ON cte.productid = kpm.productid 
ORDER BY cte.id 
0
SELECT cte.id as keyid, pn.productname, some other columns 
FROM (SELECT k.id, some other select statements 
     FROM KeyDim k 
     JOIN KeyData kd 
       on kd.id = k.id 
     JOIN KeyProductMapping kpm 
       on kpm.id = k.id 
       and kpm.mkey = k.mkey 
     JOIN Products p 
       on p.productid = kpm.productid 
       and p.productid IN (2,4,5) 
     LEFT JOIN some more joins 
     WHERE clause conditions 
    ) CTE 
    JOIN KeyProductMapping kpm 
     on cte.id = kpm.id 
    JOIN Products pn 
     on pn.productid = kpm.productid 
ORDER BY cte.id 

は私には意味がありません

JOIN KeyProductMapping kpm 
     on kpm.id = k.id 
     and kpm.mkey = k.mkey 
JOIN Products p 
     on p.productid = kpm.productid 
     and p.productid IN (2,4,5) 

と同じです
JOIN KeyProductMapping kpm 
     on kpm.id = k.id 
     and kpm.mkey = k.mkey 
     and p.productid IN (2,4,5) 

商品にその価値がない場合ES

SELECT kd.id -- move this to main select, some other select statements 
FROM KeyData kd 

理由と同じ

なぜ

SELECT k.id, some other select statements 
    FROM KeyDim k 
    JOIN KeyData kd 
     on kd.id = k.id 

LEFT JOIN some more joins 

+0

こんにちはパパラッチ、なぜなら、「より多くの結合」の理由です。kpm.mkey = k.mkeyについては、この部分をスキップすることができます。実際には、私が言及していない結合テーブルにもう1つテーブルがあります。チェーンM主な焦点は、結合の組み合わせを減らすために、すべての表を1回だけ使用することです。 – user2406618

+0

しかし、あなたがメインクエリに必要な他の値を取得 – Paparazzi

+0

はい私は実際にはcteの値を使用していた、私のメインクエリでcte.col1、cte.col2と言う。 keydimテーブルは多くの結合に関連付けられているので、私はそれをcteに保持しました。しかし、私はこれらの結合をメインのクエリに移動して、それらの結合をcteで参照することができます。私はその点に同意します。 – user2406618

1

だけのスキーマ(エンティティと関係)をよりよく理解することなく、データとその簡単な例

select pm2.*, product.name 
    from productmapping pm1 
    join productmapping pm2 
     on pm2.keyid = pm1.keyid 
     and pm1.productid in (1) 
    join product 
     on product.id = pm2.productid 


declare @product table(id int, name varchar(20)); 
declare @map table(productid int, keyid int); 
insert into @product values 
(1, 'car'), 
(2, 'bike'), 
(3, 'plane'), 
(4, 'bus'), 
(5, 'train'), 
(45, 'cycle'); 
insert into @map values 
(1, '23'), 
(2, '987'), 
(45, '23'), 
(1, '56'); 
select pm2.*, p.name 
    from @map pm1 
    join @map pm2 
     on pm2.keyid = pm1.keyid 
     and pm1.productid in (1) 
    join @product p 
     on p.id = pm2.productid 
order by pm2.keyid; 
+0

自己結合が働いた。 私の実際のクエリでは、私は左の結合を使用しました。 最初にproductidlistのkeyidを取得し、再び一致するキーIDのための結合を残しました。 – user2406618

関連する問題