2

これに見えるテーブルt1があり、レコードがアイテム、サイズ、および日付の組み合わせで一意である場合。

item    size    date
1234    S   2013-02-11
1234    M   2013-02-11
1234    L   2013-02-11
9999    S   2013-02-11
9999    M   2013-02-11
9999    L   2013-02-11
1234    S   2013-02-13
1234    M   2013-02-13
1234    L   2013-02-13
9999    S   2013-02-13
9999    M   2013-02-13

2013-02-11と比較して2013-02-13から欠落しているアイテムとサイズを取得するにはどうすればよいですか?

私が探しているリターンは、

item    size
9999    L

私が試してみました;

SELECT ta.item, 
         ta.size
FROM t1 ta 
    LEFT JOIN t1 tb 
        ON ta.item = tb.item
            AND ta.size = tb.size
WHERE ta.date = '2013-02-11'
   AND tb.date = '2013-02-13'
   AND tb.size IS NULL

SELECT item, size 
FROM t1
WHERE t1.date = '2013-02-11'
   AND NOT EXISTS (
                    SELECT item, size 
                    FROM t1
                    WHERE t1.date = '2013-02-13'
                  )

どちらも空のセットを返します。

これを機能させる唯一の方法は、一時テーブルを使用することです。

CREATE temporary table temp1
SELECT * FROM t1 WHERE date = '2013-02-11';

CREATE temporary table temp2
SELECT * FROM t1 WHERE date = '2013-02-13';

SELECT temp1.item, temp1.size FROM temp1
   LEFT JOIN temp2 
        ON temp1.item = temp2.item AND temp1.size = temp2.size
WHERE temp2.size IS NULL

一時的なテーブルは使用できなくなります。一時テーブルを使用せずにこれを実現するにはどうすればよいですか?

どうもありがとう、

(優しくしてください、私は始めたばかりです!)

4

4 に答える 4

4
SELECT  a.*
FROM
        (
            SELECT  item, size
            FROM    tableName
            WHERE   date = '2013-02-11'
        ) a
        LEFT JOIN
        (
            SELECT  item, size
            FROM    tableName
            WHERE   date = '2013-02-13'
        ) b ON  a.item = b.item AND
                a.size = b.size
WHERE b.size IS NULL
于 2013-02-23T14:16:59.487 に答える
1

集計クエリを使用します。

select item, size
from t1
group by item, size
having sum(case when date = '2013-02-11' then 1 else 0 end) = 1 and
       sum(case when date = '2013-02-13' then 1 else 0 end) = 0

これは、「グループ内のグループ」クエリの例です。条項を変更することhavingで、満たす条件に多くの柔軟性があります。例えば:

having sum(case when date = '2013-02-11' then 1 else 0 end) = 0 or
       sum(case when date = '2013-02-13' then 1 else 0 end) = 0

データには存在するが、いずれかの日に欠落している組み合わせを返します。

于 2013-02-23T15:57:53.840 に答える
0

この簡単なクエリを試すこともできます

SELECT item, size FROM dbo.Table_1 WHERE date = '2013-02-11'
EXCEPT
SELECT item, size FROM dbo.Table_1 WHERE date = '2013-02-13'
于 2013-02-23T14:31:13.757 に答える
0

他の人はあなたに有効な解決策を提供しました、そしてこの投稿は単にあなたの失敗した試みに対処し、何が欠けていてそれをどのように修正できるかを説明します。

このクエリ

SELECT ta.item, 
         ta.size
FROM t1 ta 
    LEFT JOIN t1 tb 
        ON ta.item = tb.item
            AND ta.size = tb.size
WHERE ta.date = '2013-02-11'
   AND tb.date = '2013-02-13'
   AND tb.size IS NULL

WHERE句に矛盾があるため、失敗します。tb.sizeクエリは、がNULLである行を見つけようとしています。これは、インスタンスがそのtbインスタンスと一致しなかったことを意味ta、特定の値です。これで、に一致するものがない場合、そのすべての列がNULLとして返されます。これには、が含まれます。つまり、値と等しくなると同時にnullになることはできません。 tb.datetbtb.date

明らかに、あなたの意図は異なっていました。テーブルの1つのサブセットを(同じテーブルの)別のサブセットに左結合したかったのです。その場合、参加するサブセットを定義する条件をON句に入れる必要があります。つまり、両方のインスタンスの両方itemsize列が一致するという唯一の条件ではなく、それらの列が一致、他のインスタンスdateが特定の値であるという結合された条件で参加します。だから、これはあなたが代わりに持っているべきものです:

SELECT ta.item, 
         ta.size
FROM t1 ta 
    LEFT JOIN t1 tb 
        ON ta.item = tb.item
            AND ta.size = tb.size
            AND tb.date = '2013-02-13'
WHERE ta.date = '2013-02-11'
   AND tb.date = '2013-02-13'
   AND tb.size IS NULL

他のクエリ

SELECT item, size 
FROM t1
WHERE t1.date = '2013-02-11'
   AND NOT EXISTS (
                    SELECT item, size 
                    FROM t1
                    WHERE t1.date = '2013-02-13'
                  )

と混同EXISTSした結果のようINです。

まず、EXISTSがどのように機能するか。trueサブクエリが空でない行セットを返すと、それが返されます。どの列でもかまいません。行の存在だけが重要です。何も返されない場合、結果はfalseです。このように、クエリは次のようになります。

dateであり、の行'2013-02-11'がないすべての行を返しdate = '2013-02-11'ます。

あなたはおそらくそのクエリによって次のようなことを言うつもりでしたが:

ANDでありdate同じandおよびofを持つ対応する行がないすべての行を返します。'2013-02-11' itemsizedate'2013-02-11'

つまり、EXISTSサブクエリをメインクエリと相関sizeさせる必要があります。つまり、現在の行をitemEXISTSテストに含める必要があります。したがって、これは修正がどのように見えるかです:

SELECT item, size 
FROM t1 ta
WHERE ta.date = '2013-02-11'
   AND NOT EXISTS (
                    SELECT item, size 
                    FROM t1 tb
                    WHERE tb.date = '2013-02-13'
                      AND ta.item = tb.item
                      AND ta.size = tb.size
                  )

一方、のNOT IN代わりに使用するように同じクエリを書き直すことができますNOT EXISTS。ここ:

SELECT item, size 
FROM t1
WHERE date = '2013-02-11'
   AND (item, size) NOT IN (
                            SELECT item, size 
                            FROM t1
                            WHERE date = '2013-02-13'
                           )

これは基本的に言う:

(item, size)のペアがのペアセットにdate = '2013-02-11'ないすべての行を返します。(item, size)date = '2013-02-11'

IN/クエリは、対応する/NOT INクエリよりも明確に見えることがよくあります。2つが同じクエリプランになるかどうかは別の問題であり、どちらの方法を使用するかを決定する前にテストする必要があります(もちろん、それはその方法にも当てはまります)。EXISTSNOT EXISTSLEFT JOIN + WHERE IS NULL

于 2013-02-23T17:39:20.467 に答える