2012-03-26 11 views
0

うまくいけば、簡単に質問できますが、私の心は今日の午後にはうまく機能しません。私は、次の表を持っている:すべての部品が在庫されているアイテムを見つける

tblCocktail 
CockTailID CocktailName 
1   Alexander 

tblCocktailIngredient 
CocktailID IngredientID Amount UnitID 
1   1    3  1 
1   2    3  1 
1   3    3  1 

tblIngredient 
IngredientID IngredientName OnHandAmount OnHandUnitID 
1    Cognac   .75   2 
2    Creme de Cacao .9    2 
3    Cream   .5    2 

tblUnitConversion 
FromUnitID ToUnitID Factor 
1    2   100 

私は何をしようとしていることは、私はすべての成分の手元に十分なを持っているので、私が作ることができるカクテルのリストを見つけることです。私は、次のクエリを持っている:全ての成分は、上に十分な量を持っているところ

SELECT tblCocktail.CocktailName 
FROM tblCocktail INNER JOIN (tblIngredient INNER JOIN (tblCocktailIngredient INNER JOIN tblUnitConversion ON tblCocktailIngredient.UnitID = tblUnitConversion.ToUnitID) ON (tblIngredient.IngredientID = tblCocktailIngredient.IngredientID) AND (tblIngredient.OnHandUnit = tblUnitConversion.FromUnitID)) ON tblCocktail.CocktailID = tblCocktailIngredient.CocktailID 
WHERE ((([tblCocktailIngredient].[Amount]*[Factor])<[tblIngredient].[OnHandAmount])); 

これはONHANDは量よりも大きく、すべてのカクテルとの関連成分のリストが表示されます、しかし、私は唯一のカクテルを一覧表示したいですハンド。

+0

Hosは他のテーブルに関連するtblUnitConversionですか? 「tblIngredient」の行に匹敵するために、tblCocktailIngredientの行の金額に100を掛けなければならないと指定しようとしていますか? – jhenderson2099

+0

実際、tblIngredientの行のOnHandAmountには、tblCocktailIngredientの「Amount」フィールドと比較するために100を掛けなければなりません。 – NickHeidke

+0

あなたは「NO成分が必要な量よりも少ないところ」、すなわち「存在しない」などと言う必要があります。 – Ben

答えて

1
SELECT tblCocktail.CocktailName 
FROM tblCocktail 
WHERE ( SELECT COUNT(*) 
      FROM tblCocktailIngredient 
      WHERE tblCocktailIngredient.CocktailID = tblCocktail.CockTailID) 
     = 
     ( SELECT COUNT(*) 
      FROM tblIngredient 
        INNER JOIN (tblCocktailIngredient 
           INNER JOIN tblUnitConversion 
            ON tblCocktailIngredient.UnitID = tblUnitConversion.FromUnitID) 
         ON (tblIngredient.IngredientID = tblCocktailIngredient.IngredientID) 
          AND (tblIngredient.OnHandUnitId = tblUnitConversion.ToUnitID) 


      WHERE [tblCocktailIngredient].[Amount] <= [tblIngredient].[OnHandAmount]*[Factor] 
        AND tblCocktailIngredient.CocktailID = tblCocktail.CocktailID) 
0

私は、これはあなたが探しているものであると信じて:

select result1.CocktailName 
from (
    select tblCocktail.CocktailName, count(*) as NumIngredientsPerCocktail 
    from tblCocktail 
    inner join tblCocktailIngredient 
     on tblCocktail.CocktailID = tblCocktailIngredient.CocktailID 
    group by tblCocktail.CocktailName 
) as result1 
inner join (
    select tblCocktail.CocktailName, count(*) as NumberAvailableIngredientsForCocktail 
    from tblCocktail 
    inner join tblCocktailIngredient 
     on tblCocktail.CocktailID = tblCocktailIngredient.CocktailID 
    inner join tblIngredient 
     on tblCocktailIngredient.IngredientID = tblIngredient.IngredientID 
    inner join tblUnitConversion 
     on tblUnitConversion.FromUnitID = tblCocktailIngredient.UnitID 
     and tblUnitConversion.ToUnitID = tblIngredient.OnHandUnitID 
    where tblIngredient.OnHandAmount * tblUnitConversion.Factor >= tblCocktailIngredient.Amount 
    group by tblCocktail.CocktailName 
) as result2 
on result1.NumIngredientsPerCocktail = result2.NumberAvailableIngredientsForCocktail 
and result1.CocktailName = result2.CocktailName 
+0

これはMS Accessで実行されません、十分な括弧がありません。 – Fionnuala

+0

カッコが一致しているようです。アクセスは他の何かについて不平を言う必要がありますか?このSQLはSQL Serverで動作します。 – jhenderson2099

+0

Accessは結合を再順序付けしないため(私の答えで私の不平を見てください)、結合のすべてのペアの周りにかっこを入れてください。 – Simon

1

ない簡単なクエリ、アクセスが複雑な外部結合について非常に明確にするためにあなたを必要とするため。

SELECT tblCocktail.CocktailID, tblCocktail.CocktailName, sum(IIf(isnull(onhand.IngredientID),1,0)) AS missingIngredients 
FROM (tblCocktail INNER JOIN tblCocktailIngredient ON tblCocktail.CocktailID=tblCocktailIngredient.CocktailID) 
LEFT JOIN (
    SELECT tblIngredient.IngredientID, tblIngredient.OnHandAmount*tblUnitConversion.Factor AS OnHandAmount, tblUnitConversion.FromUnitID AS OnHandUnitID 
    FROM tblIngredient INNER JOIN tblUnitConversion ON tblUnitConversion.ToUnitID=tblIngredient.OnHandUnitID 
) AS onhand 
ON (tblCocktailIngredient.IngredientID=onhand.IngredientID) AND (tblCocktailIngredient.UnitID=onhand.OnHandUnitID) AND (tblCocktailIngredient.Amount<=onhand.OnHandAmount) 
GROUP BY tblCocktail.CocktailID, tblCocktail.CocktailName 
HAVING sum(IIf(isnull(onhand.IngredientID),1,0))=0 

(編集:私は一つだけサブクエリを必要実現)

詳しく説明するために、私が使用アウター成分がカクテルに十分な量で手にあるかどうかを識別するために参加します。それから、カクテルによるグループ分けは、HAVING句に欠けている/欠けていない成分の数を数えることができます。

「onhand」サブクエリは、指定されたユニットで手元にあるものを見やすくするために、名前付きクエリーとして作成するのに便利かもしれないことに注意してください。

+0

クエリを洗練した後、私はアクセスについての私の言動にもかかわらず、これは私がIIf(isnull())アクセス方言とは別に、他のデータベースでもこのクエリを実行する方法であることに気付きました。私の最初のアプローチは、Accessが拒否したあいまいな外部結合を持っていましたが、今は不正確な結果を与えてしまったはずです。 – Simon

+0

HAVING句の右側にある「0」を「1」または「2」に変更すると、「1つまたは2つ以上の成分があれば何ができますか? – Simon