Php 来自4个表的复杂SQL
我需要一些帮助来为一个包含四个表的PHP应用程序编写SQL语句。情况是这样的Php 来自4个表的复杂SQL,php,mysql,Php,Mysql,我需要一些帮助来为一个包含四个表的PHP应用程序编写SQL语句。情况是这样的 表B中的每种艺术都有表D中的类别列表 表A中的每个PlaceID在表C中都有一个类别列表 我需要从表B中选择艺术来填充表a中的PlaceID,但艺术和PlaceID必须至少有一个共同的类别 如果能得到任何帮助,我将不胜感激 表A 表B 表C 表D 对于给定的myPlaceID,您可以找到可能的Art值,如下所示: SELECT DISTINCT B.Art FROM B INNER JOIN D
- 表B中的每种艺术都有表D中的类别列表
- 表A中的每个PlaceID在表C中都有一个类别列表
对于给定的myPlaceID,您可以找到可能的Art值,如下所示:
SELECT DISTINCT B.Art
FROM B
INNER JOIN D
ON D.ArtID = B.ArtID
INNER JOIN C
ON C.Category = D.Category
WHERE C.PlaceID = :myPlaceID;
在此查询中不需要表A
这是一本书。请注意,对于PlaceID的现有值(1,2,3),您将始终获得2条记录作为结果(Art1,Art2),以及您提供的示例数据。因此,您可能需要使用一些其他数据来获得结果中的更多变化。假设两个表
tablec
和tabled
与类别相关,则可以执行以下操作:
SELECT
b.Art,
a.PlaceId,
COUNT(DISTINCT c.Category) AS TotalCategories
FROM tableA AS a
INNER JOIN tablec AS c ON a.placeID = c.PlaceID
INNER JOIN tabled AS d ON d.Category = c.Category
INNER JOIN tableB AS b ON b.ArtID = d.ArtID
GROUP BY b.Art, a.PlaceId
HAVING COUNT(DISTINCT c.Category) > 0;
这将只提供至少有一个共同类别的场所和艺术,以及共同类别的计数
这将为您提供:
| Art | PlaceID | TotalCategories |
|------|---------|-----------------|
| Art1 | 1 | 2 |
| Art1 | 2 | 2 |
| Art2 | 1 | 2 |
| Art2 | 2 | 1 |
正如您所见,这只返回了艺术1、2和场所1、2,因为它们是唯一的艺术,场所有多个共同类别
旁注:在您的桌子设计中,您缺少艺术与场所之间的多对多连接桌子。因此,如果category
只是将tablec与tabled关联起来,那么您可以去掉tablec
或tabled
,这样您将在同一个表中同时拥有placeid
和artid
,它们将充当多对多连接表。那么表C和表D中的catehgorities关联吗?有一个类别表,然后有另一个将a+B连接到类别的表不是更好吗?表C和表D中的类别是相关的,Cat1在两个表中是相同的。我不明白你关于连接表的观点。地方和艺术之间的关系缺失了,艺术和地方是如何相互联系的?还有,为什么你不使用可读的名称,如类别、艺术和场所
而不是表1、表2、表3?我的意思是,按照你目前的设计,你不能在一个查询中连接四个表,你缺少艺术和场所之间的关系。@Mahmoud,在我的实际应用程序中,我有真实的名称。。。现在艺术和地方之间没有明确的关系。。。唯一的关系是,地方允许某些类别,艺术可分为几个类别。我需要的是根据类别列出每个地方的合格艺术。@trincot,谢谢让我运行这个,看看我得到了什么。@trincot,谢谢你的回复。你的解决方案很接近我想要的,但不完全是。在您发送的小提琴中,当:myPlaceID=3时,不应返回Art 1,因为Art 1仅允许cat2和3,但placeID仅支持Cat 1。请问您是否有办法修改查询。。记住这是逻辑…每个PlaceID都支持一个类别列表。。只有这一类的艺术才应该被允许。谢谢你的帮助我不明白你说Art1只允许cat2和CAT3,因为在你的问题中,你在表D中列出了Art1与cat1相关的第一条记录。你能澄清一下吗?忽略我最后的评论。我犯了个错误。你真的满足了我的需要。
TabID | ArtID | Category
1 | 1 | Cat1
2 | 1 | Cat2
3 | 1 | Cat3
4 | 2 | Cat1
5 | 2 | Cat2
SELECT DISTINCT B.Art
FROM B
INNER JOIN D
ON D.ArtID = B.ArtID
INNER JOIN C
ON C.Category = D.Category
WHERE C.PlaceID = :myPlaceID;
SELECT
b.Art,
a.PlaceId,
COUNT(DISTINCT c.Category) AS TotalCategories
FROM tableA AS a
INNER JOIN tablec AS c ON a.placeID = c.PlaceID
INNER JOIN tabled AS d ON d.Category = c.Category
INNER JOIN tableB AS b ON b.ArtID = d.ArtID
GROUP BY b.Art, a.PlaceId
HAVING COUNT(DISTINCT c.Category) > 0;
| Art | PlaceID | TotalCategories |
|------|---------|-----------------|
| Art1 | 1 | 2 |
| Art1 | 2 | 2 |
| Art2 | 1 | 2 |
| Art2 | 2 | 1 |