2012-09-20 151 views
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 with Data

+2

感謝張貼表DDL/DML,但如果你創建了一個工作模型,將會變得更好[SQL小提琴(http://sqlfiddle.com/) – Taryn

+1

像這樣? http://sqlfiddle.com/#!2/83667/6 – KLee1

+0

完美,謝謝! :) – Taryn

回答

3

如果我解決了這個問題,我會加入四個表與他們的連接柱(特別是外鍵)然後在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 Demo

+0

您應該能夠完成整個工作,選擇所有可以滿足其購物清單的人作爲單一商店,以及他們可以這樣做的商店名稱,而不需要'@ personID'表示法。 –

+0

@JonathanLeffler我只是在回答OP的內容「我的問題是,給定一個人或者他們的ID ......」。無論如何,我只會更新答案:)謝謝。 –

+0

這裏有拐角的情況嗎?如果該人在他們的名單上沒有任何東西會怎麼樣在這種情況下,他們可以去任何商店。對這種情況最好只是有一個if語句? – KLee1

1

@JohnWoo:爲什麼分開?

另外一...

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 [email protected] 
GROUP BY store_id 
HAVING COUNT(*)=(
    SELECT COUNT(*) 
    FROM lists 
    WHERE [email protected] 
);