0

私は4つの(関連する)テーブルを持っています

CAKETABLE
CAKE      ICING

RESERVEDSPRINKLES
CAKE      SPRINKLE

SPRINKLETABLE
SPRINKLE  CONSUMED

ICINGTABLE
ICING     CONSUMED

各ケーキにはちょうど 3 つのスプリンクルと 1 つのアイシングがあります。

データベースにクエリを実行し、アイシングもスプリンクルも消費 = '1' ではない、1 つのアイシングと 3 つのスプリンクルを持つすべてのケーキを取得したいと考えています。

それでは、疑似挿入データを見てみましょう: INSERT INTO ICINGTABLE (vanilla, 0), (chocolate, 0);

INSERT INTO SPRINKLETABLE (red, 0), (blue, 0), (green, 0), (orange, 0), (purple, 0),(pink, 0);

INSERT INTO CAKETABLE (cake1, vanilla), (cake2, chocolate);

INSERT INTO RESERVEDSPRINKLES (cake1, red), (cake1, blue), (cake1, green), (cake2, orange), (cake2, purple), (cake2, pink);

これで、バニラのアイシングと赤、青、緑のスプリンクルを添えたケーキ 1 と、チョコレートのアイシングとオレンジ、紫、ピンクのスプリンクルを添えたケーキ 2 ができました。

クエリを実行すると、戻りたい

CAKES
cake1
cake2

ケーキに消費された部分がない場合にのみ、したがって、1 つのスプリンクルが消費済みとしてマークされていても、クエリからそのケーキ全体を省略したいと考えています。次のクエリは、アイシングに対してまさにそれを行います。

SELECT CAKE
FROM CAKETABLE as c
INNER JOIN (SELECT * FROM ICINGTABLE WHERE CONSUMED = '0') as i
ON c.ICING = i.ICING;

しかし、ふりかけについては、私は問題を抱えています。上記と同じ手法を使用すると、クエリは次のように返されます。

CAKE
cake1
cake1
cake1
cake2
cake2
cake2

DISTINCT でそれを排除できますが、スプリンクルが消費された = '0' の場合、逆の機能が必要なときにそのケーキがリストに表示されるため、まだ正しくありません (ケーキは、すべてのスプリンクルが消費された場合にのみ表示されます = '0' )

誰かがこれに適したタイトル名を持っている場合は、それをいただければ幸いです。説明的で短いものは考えられません。

4

3 に答える 3

1

not existsアイシングやスプリンクルが消費されないように要求するために使用できます。

select  cake
from    caketable c
where   not exists
        (
        select  *
        from    icingtable i
        where   i.cake = c.cake
                and i.consumed = '1'
        )
        and not exists
        (
        select  *
        from    sprinkletable s
        where   s.cake = c.cake
                and s.consumed = '1'
        )
于 2012-07-25T18:21:38.647 に答える
0

ケーキには常に正確に 3 つのスプリンクルがあると仮定すると、 CakeGROUP BYを使用HAVINGして、未消費のスプリンクルが 3 つないケーキをフィルタリングできます。

SELECT CAKE
FROM CAKETABLE as C
INNER JOIN (
    SELECT * FROM ICINGTABLE WHERE CONSUMED = '0'
) as I ON C.CAKE = I.CAKE
INNER JOIN (
    SELECT CAKE FROM SPRINKLETABLE 
    WHERE CONSUMED = '0'
    GROUP BY CAKE
    HAVING COUNT(*) = 3
) as S ON C.CAKE = S.CAKE;
于 2012-07-25T18:23:15.460 に答える
0

私はあなたが望むことを次のようにすると思います:

select ct.cake
from caketable ct join
     reservedsprinkle rs
     on ct.cake = rs.cake join
     sprinkletable st
     on rs.sprinkle = st.sprinkle join
     icingtable it
     on ct.cake = it.cake
where it.consumed = 0
group by ct.cake
having count(distinct rs.sprinkle) = 3 and
       sum(case when st.consumed = 1 then 1 else 0 end) = 0

これはケーキでグループ化し、ほとんどの条件を HAVING 句に入れています。データベースの設計により、ケーキにはアイシングが 1 つしかないように見えます。CAKE は CAKE テーブル内で一意であると想定しています。

于 2012-07-25T18:41:34.480 に答える