1

私は現在取り組んでいる3つのテーブルを持っています。レシピ、材料、レシピ。これは古典的な多対多の状況であり、recipeIng を使用してその問題を解決します。

ただし、かなり単純な「AND」クエリであると想定していたものを取得するのに問題があります。私が達成しようとしているのは、一度に複数の成分を検索することです。例えば:

SELECT r.recipeTitle AS recipe
FROM Recipe r
WHERE recipeID IN(
    SELECT r.recipeID
    FROM recipeIng il, Ingredient i
    WHERE (il.ingredientID = i.ingredientID)
    AND (il.recipeID = r.recipeID)
    AND (i.ING LIKE '%cheese%' AND i.ING LIKE '%salmon%')

);

クエリの実行中、何も出力されません。ここで何が間違っているのかわかりません。どんな助けでも本当に感謝しています。

ありがとう。

4

3 に答える 3

3

したがって、基本的には、クエリしている材料を含むレシピが必要です。これは、単純な直線結合を使用して実行できます。

SELECT DISTINCT(r.recipeTitle) AS recipe
FROM Ingredient i
INNER JOIN recipeIng il ON il.ingredientID = i.ingredientID
INNER JOIN Recipe r ON r.recipeID = il.recipeID
WHERE i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%'

両方のDISTINCT()材料が含まれている場合でも、同じレシピが 2 回表示されないようにします。

両方の成分がレシピに含まれている必要がある場合は、AND代わりに を使用する必要がありますOR

于 2013-02-07T14:09:38.940 に答える
2

まず第一に、外側のクエリが必要ないため、クエリを大幅に簡素化できます。以下はまったく同じです。

SELECT r.recipeTitle AS recipe
FROM recipeIng il, Ingredient i, Recipe r
WHERE (il.ingredientID = i.ingredientID)
AND (il.recipeID = r.recipeID)
AND (i.ING LIKE '%cheese%' AND i.ING LIKE '%salmon%')

第二に、これらすべてのブラケットは必要ありません。

SELECT r.recipeTitle AS recipe
FROM recipeIng il, Ingredient i, Recipe r
WHERE il.ingredientID = i.ingredientID
AND   il.recipeID = r.recipeID
AND   i.ING LIKE '%cheese%' 
AND i.ING LIKE '%salmon%'

第三に、テーブル間の関係をより明確にするために、テーブルを内部結合する必要があります。

SELECT r.recipeTitle AS recipe
FROM recipeIng il JOIN 
     Ingredient i ON  il.ingredientID = i.ingredientID JOIN
     Recipe r ON il.recipeID = r.recipeID
WHERE i.ING LIKE '%cheese%' 
AND   i.ING LIKE '%salmon%'

この時点で、問題は明確になっているはずです。2 つの可能性があり、2 つは 1 つよりも可能性が高いです。

1)INGフィールドは、レシピのすべての材料を 1 つのフィールドに格納します。この場合、材料にチーズとサーモンの両方が必要なレシピはありません。

2) あなたのINGフィールドには、行ごとに 1 つの成分しか保存されません。Cheeseただし、 と の両方を含む単一の行を求めていますSalmon。これはあなたの意図ではないため、クエリは間違っています。

-- SELECT ALL RECIPES USING CHEESE *OR* SALMON
SELECT r.recipeTitle AS recipe
FROM recipeIng il JOIN 
     Ingredient i ON  il.ingredientID = i.ingredientID JOIN
     Recipe r ON il.recipeID = r.recipeID
WHERE i.ING LIKE '%cheese%' 
AND   i.ING LIKE '%salmon%'

-- SELECT ALL RECIPES USING CHEESE *AND* SALMON
SELECT r.recipeTitle AS recipe
FROM recipeIng il JOIN 
     Ingredient iCheese 
         ON  il.ingredientID = i.ingredientID 
         AND i.ING LIKE '%cheese%'  JOIN
     Ingredient iSalmon 
         ON  il.ingredientID = i.ingredientID 
         AND i.ING LIKE '%salmon%'  JOIN 
     Recipe r ON il.recipeID = r.recipeID

上記は単なる例であることに注意してください-スキーマを知らなくても、これらは単なるヒントと提案です:)

于 2013-02-07T14:05:07.303 に答える
2

i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%'の代わりに使用しAND、 を追加GROUP BY r.recipeIDHAVING COUNT(DISTINCT i.ING ) = 2て、選択したr.recipeIDものが両方を持つようにしINGます。

SELECT r.recipeTitle AS recipe
FROM Recipe r
WHERE recipeID IN(
    SELECT r.recipeID
    FROM recipeIng il
    INNER JOIN Ingredient i ON il.ingredientID = i.ingredientID 
    WHERE il.recipeID = r.recipeID
      AND (i.ING LIKE '%cheese%' OR i.ING LIKE '%salmon%')
    GROUP BY r.recipeID
    HAVING COUNT(DISTINCT i.ING ) = 2
);

SQL フィドルのデモ

したがって、r.recipeIDがそれらのうちの 1 つしかない場合、 はCOUNT(DISTINCT i.ING )2 に等しくならず、そのため除去されます。

HAVING COUNT(DISTINCT i.ING ) = 2、チーズとサーモンの 2 つのタグがまったくないレシピを提供します。少なくとも 2 つの材料の両方を含むレシピを探している場合は、 を使用して`HAVING COUNT(DISTINCT i.ING ) >= 2ください。

これは、材料が行ごとに 1 つの値としてフィールドに入力されていることを前提としています。ING

于 2013-02-07T14:05:09.527 に答える