对于此问题,请考虑以下3个表:
Event
id (pk)
title
Event_Category
event_id (pk, fk)
category_id (pk, fk)
Category
id (pk)
description
我觉得很琐碎...... :)每个事件都可以分为零个或多个类别,总共有4个类别。 在我的应用程序中,我想查看和编辑特定事件的类别。在图形上,事件将与所有类别一起显示,并且复选框将指示事件是否属于该类别。更改和保存选择将导致中间表Event_Category的修改。 但首先:如何为特定事件选择此项?我需要的查询实际上总是返回4行,即存在的类别数。
以下仅返回id = 11的事件所属类别的条目。尝试使用外连接并未在结果中提供更多行。
SELECT e.id, c.omschrijving
FROM Event e
INNER JOIN Event_Categorie ec ON e.id = ec.event_id
INNER JOIN Categorie c ON c.id = ec.categorie_id
WHERE e.id = 11
或者我应该从查询中的Category表开始?希望有一些提示:) TIA,Klaas
更新 是的我做了但仍未找到答案。但是我通过从查询中省略Event表来简化了这个问题,因为该表仅用于查看事件描述。
SELECT * from Categorie c LEFT JOIN Event_Categorie ec ON c.id = ec.categorie_id WHERE ec.event_id = 11;
简化的2表查询仅使用查找表和链接表,但仍然只返回2行,而不是在Categorie表中返回总共4行。 我的猜测是在加入后应用了WHERE子句,因此排除了未加入链接表的行。在我的应用程序中,我使用子查询解决了问题,但我仍然想知道什么是最佳解决方案。
答案 0 :(得分:0)
您想要的是所有类别的列表,以及有关该类别是否在您的活动类别列表中的信息。
所以,你可以这样做:
SELECT
*
FROM
Category
LEFT JOIN Event_Category ON category_id = id
WHERE
event_id = 11
对于不属于您事件的类别,和event_id列将为NULL。
您还可以创建一个列(下面名为has_category),用于查看事件是否具有此类别而不是与NULL进行比较:
SELECT
*,
event_id IS NOT NULL AS has_category
FROM
Category
LEFT JOIN Event_Category ON category_id = id
WHERE
event_id = 11
编辑:这看起来就像你说你在编辑时所做的那样。我测试了它似乎是正确的。你确定你正在运行这个查询,并且那些带有NULL的行不会被忽略吗?
答案 1 :(得分:0)
查询
SELECT * FROM Categorie;
返回4行:
+----+--------------+-------------------------------------+--------------------------------------+
| id | omschrijving | afbeelding | afbeelding_klein |
+----+--------------+-------------------------------------+--------------------------------------+
| 1 | Creatief | images/categorieen/creatief420k.jpg | images/categorieen/creatief190k.jpg |
| 2 | Sportief | images/categorieen/sportief420k.jpg | images/categorieen/sportief190kr.jpg |
| 4 | Culinair | images/categorieen/culinair420k.jpg | images/categorieen/culinair190k.jpg |
| 5 | Spirit | images/categorieen/spirit420k.jpg | images/categorieen/spirit190k.jpg |
+----+--------------+-------------------------------------+--------------------------------------+
4 rows in set (0.00 sec)
BUT: 查询
SELECT *
FROM Categorie
LEFT JOIN Event_Categorie ON categorie_id = id
WHERE event_id = 11;
返回2行:
+----+--------------+-------------------------------------+-------------------------------------+----------+--------------+
| id | omschrijving | afbeelding | afbeelding_klein | event_id | categorie_id |
+----+--------------+-------------------------------------+-------------------------------------+----------+--------------+
| 1 | Creatief | images/categorieen/creatief420k.jpg | images/categorieen/creatief190k.jpg | 11 | 1 |
| 4 | Culinair | images/categorieen/culinair420k.jpg | images/categorieen/culinair190k.jpg | 11 | 4 |
+----+--------------+-------------------------------------+-------------------------------------+----------+--------------+
2 rows in set (0.00 sec)
所以我仍然需要子查询...并且LEFT JOIN在显示CAtegorie表的所有行时无效,无论是否与链接表匹配。
然而,这个查询做了我想要它做的事情:
SELECT *
FROM Categorie c
LEFT JOIN (SELECT * FROM Event_Categorie ec WHERE ec.event_id = 11 ) AS subselect ON subselect.categorie_id = c.id;
结果:
+----+--------------+-------------------------------------+--------------------------------------+----------+--------------+
| id | omschrijving | afbeelding | afbeelding_klein | event_id | categorie_id |
+----+--------------+-------------------------------------+--------------------------------------+----------+--------------+
| 1 | Creatief | images/categorieen/creatief420k.jpg | images/categorieen/creatief190k.jpg | 11 | 1 |
| 2 | Sportief | images/categorieen/sportief420k.jpg | images/categorieen/sportief190kr.jpg | NULL | NULL |
| 4 | Culinair | images/categorieen/culinair420k.jpg | images/categorieen/culinair190k.jpg | 11 | 4 |
| 5 | Spirit | images/categorieen/spirit420k.jpg | images/categorieen/spirit190k.jpg | NULL | NULL |
+----+--------------+-------------------------------------+--------------------------------------+----------+--------------+
4 rows in set (0.00 sec)
答案 2 :(得分:0)
问题是您已经通过eventid过滤了结果。正如您在结果中看到的那样,两个类别(Sportief和Spirit)没有事件。因此,正确的SQL语句(使用SQL Server语法;可能需要一些翻译)是:
SELECT *
FROM Categorie
LEFT JOIN Event_Categorie ON categorie_id = id
WHERE (event_id IS NULL) OR (event_id = 11);
答案 3 :(得分:0)
最后我找到了正确的查询,没有必要进行子选择。但WHERE子句在加入后起作用,因此不再是连接的一部分。该解决方案是使用额外条件扩展ON子句。现在,对于不匹配的类别,所有4行都返回NULL;
SELECT *
FROM Categorie
LEFT JOIN Event_Categorie ON categorie_id = id AND event_id = 11;
所以底线是在ON子句中添加一个额外条件与在WHERE子句中按相同条件过滤掉行的效果不同!