5

テーブル

recipe_food_xref
recipe_id int
food_id int

レシピに 1 つの食品しかなく、その食品が特定の食品である、recipe_food_xref 内の 1 つのレコードを見つける必要があります。

それ自体に完全に結合して機能します。

SELECT x1.recipe_id FROM recipe_food_xref x1
INNER JOIN recipe_food_xref x2 ON x2.recipe_id = x1.recipe_id
WHERE x1.food_id = 1
GROUP BY x1.recipe_id
HAVING COUNT(x2.recipe_id) = 1

それは少し醜いようですが、もっと良い方法があるかどうか知りたいです。

サンプル データを含む SqlFiddle を次に示します。基本的には、food_id:1 があり、複数の food_id を持たないため、recipe_id:1 を見つけたいと考えています。

http://sqlfiddle.com/#!3/6d474/1

4

4 に答える 4

2
SELECT recipe_id 
FROM recipe_food_xref
GROUP BY recipe_id
HAVING sum(case when food_id = 1 then 1 else 0 end) = 1
and sum(case when food_id <> 1 then 1 else 0 end) = 0

SQLFiddle デモ

于 2013-10-02T13:11:01.437 に答える
1

これは私の最初の試みでした:

SELECT recipe_id
FROM recipe_food_xref
GROUP BY recipe_id
HAVING COUNT(food_id) = 1 AND SUM(food_id) = 1;

一般的な形式はHAVING COUNT(FOOD_ID) = 1 AND SUM(FOOD_ID) = <food id>. これは、food_id が 1 つしかない場合、合計が id に等しいため機能します。

ユルゲンの答えに似ているようですが、より簡単です。私は何か見落としてますか?

また、テーブルを余分にスキャンする必要がある次のことも試しましたが、これまでALLキーワードを使用したことがなかったので、興味深いと思いました。

SELECT recipe_id
FROM recipe_food_xref AS r
WHERE 1 = ALL (SELECT food_id FROM recipe_food_xref WHERE r.recipe_id=recipe_id);

http://sqlfiddle.com/#!3/6d474/26

于 2013-10-02T13:54:21.320 に答える
0
select *
from recipe_food_xref x
where not exists (
                   select i.food_id
                   from recipe_food_xref i
                   where i.recipe_id = x.recipe_id and
                         i.food_id <> x.food_id
                 ) 
-- if this is omitted you get all recipes having just one food:
      and x.food_id = 1
于 2013-10-02T13:17:57.767 に答える