2012-09-20 118 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] 
);