2016-04-08 12 views
2

私は製品のテーブルとウィジェットのテーブルを持っています。selectステートメント内のサブクエリを結合にリファクタリングする

製品はいくつかのウィジェットから構築されており、どのウィジェットがどの製品にリンクされているかを示すリンクテーブルがあります。

ウィジェットはexpiredとマークすることができます。つまり、新しい商品に追加することはできません。

スキーマとサンプルデータ次sqlFiddleに -

私は次の規則与えられた特定の製品のすべての適格なウィジェットを表示するクエリたい:

  1. ウィジェットを示すべきではありません期限切れとマークされている場合
  2. 上記のルールの例外として - ウィジェットが有効期限切れとマークされているが、既に製品にリンクされている場合は、表示する必要があります。
  3. ウィジェットが既に製品にリンクされている場合、それは'selected'

としてマークされなければならない、私は上記のすべてのルール作品次のクエリを得て、満足しました:

select 
    data.WidgetName, 
    data.expired, 
    case 
     when data.ID in (select data_id from Widget_link where productId = 1) 
     then 1 
     else 0 
    end as selected 
from Widget_data data 
left outer join Widget_link link 
    on data.ID = link.data_id and data.expired = 1 
where (data.expired = 0 or (data.expired = 1 and link.productId = 1)) 

を私はいくつかの種類の結合のクエリの選択部分内のサブクエリをリファクタリングする方法を探したいと思います。 productIdを2か所に配置するのではなく、where節を使用してフィルタリングできるビューを作成しようとしています。これは可能ですか?

答えて

3

簡略化のため、以下のようなJOINに基づいてクエリを評価することができ、内部クエリはまったく必要ありません。

select data.WidgetName, 
    case when link.id is not null then 1 else 0 end as selected 
from Widget_data data 
left outer join Widget_link link 
    on data.ID = link.data_id and link.productId = 1 
where data.expired=0 or link.id is not null 

Demo SQL fiddle

+0

これはうまくいくようです - ありがとう! – John

0

あなたは、SELECTリストから結果をカバーするためにSQL CTE (Common Table Expression)を使用し、

あなたも、あなたのコード内でSQL statements with multiple CTE'sを作成することができ、単一のSQL文で使用することができます

私が示唆していることは、次のように視覚的に要約できます。

WITH cte AS (
    SELECT ..... FROM ..... 
), 
other_cte AS (
    SELECT ..... FROM ..... 
) 
SELECT * 
FROM cte 
INNER JOIN other_cte ON... 
関連する問題