7

次のように、人、食料品店、店で購入できる商品を含むデータベースがあるとします。

Stores               People                Foods
-----------------    ------------------    ------------------
| id |   name   |    | id |   name    |    | id |   name    |
-----------------    ------------------    ------------------
| 1  |  Giant   |    | 1  | Jon Skeet |    | 1  | Tomatoes  |
| 2  |  Vons    |    | 2  | KLee1     |    | 2  | Apples    |
| 3  | Safeway  |    ------------------    | 3  | Potatoes  |
-----------------                          ------------------

どの店舗が何を販売しているかを追跡する追加のテーブルがあります。

Inventory
--------------------
| store_id| food_id|
--------------------
| 1       | 1      |
| 1       | 2      |
| 2       | 1      |
| 3       | 1      |
| 3       | 2      |
| 3       | 3      |
--------------------

そして、買い物リストが載っている別のテーブルがあります

Lists
---------------------
| person_id| food_id|
---------------------
| 1        | 1      |
| 1        | 2      |
| 1        | 3      |
| 2        | 1      |
| 2        | 3      |
---------------------

私の質問は、人またはその ID が与えられた場合、リストにあるすべてのものを手に入れるために、どの店に行くことができるかを把握するための最良の方法は何かということです。MySQL でこれらのタイプの計算のパターンはありますか?

私の試み(非常に醜くて面倒)は次のようなものです:

-- Given that _pid is the person_id we want to get the list of stores for.

SELECT stores.name, store_id, num, COUNT(*) AS counter
FROM lists
    INNER JOIN inventory 
        ON (lists.food_id=inventory.food_id)
    INNER JOIN (SELECT COUNT(*) AS num
            FROM lists WHERE person_id=_pid 
            GROUP BY person_id) AS T
    INNER JOIN stores ON (stores.id=store_id)
WHERE person_id=_pid 
GROUP BY store_id
HAVING counter >= num;

御時間ありがとうございます!

データを使用して SQL Fiddle を編集する

4

2 に答える 2

3

この問題を解決するには、4 つのテーブルをリンク列 (具体的には外部キー) で結合してから、句のサブクエリを使用しHAVINGて、各人のリストのアイテム数をカウントします。これを試してみてください。

SET @personID := 1;

SELECT  c.name
FROM    Inventory a
        INNER JOIN Foods b
            ON a.food_id = b.id
        INNER JOIN Stores c
            ON a.store_id = c.id
        INNER JOIN Lists d
            ON d.food_id = b.id
WHERE   d.person_id = @personID
GROUP BY c.name
HAVING   COUNT(DISTINCT d.food_id) =
     (
        SELECT COUNT(*)
        FROM Lists
        WHERE person_ID = @personID
     )

SQLFiddle デモ

于 2012-09-21T00:29:42.003 に答える
1

@JohnWoo:なぜDISTINCTなのですか?

もう一つ...

SET @pid=2;

SELECT store_id, name
FROM inventory 
  JOIN lists ON inventory.food_id=lists.food_id
  JOIN stores ON store_id=stores.id
WHERE person_id=@pid
GROUP BY store_id
HAVING COUNT(*)=(
  SELECT COUNT(*)
  FROM lists 
  WHERE person_id=@pid
);
于 2012-09-21T00:49:23.333 に答える