5

我有以下表格:

CREATE TABLE `accommodations` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL DEFAULT '',
  PRIMARY KEY (`id`)
) 

CREATE TABLE `accommodations_exclude` (
  `id_accommodation` int(11) unsigned NOT NULL,
  `id_course` int(11) NOT NULL,
  UNIQUE KEY `id_course` (`id_course`,`id_accommodation`)
) 

在住宿表中有 4 条记录,在住宿排除中还有更多。现在我想要一个查询,它总是给我来自住宿表的所有记录,并作为额外字段加入以查看住宿是否也存在于住宿排除表中。

例如; 在 accommodation_exclude 中有一行 id_accommodation = 2, id_course = 16。

我想要一个显示以下内容的结果集:

accommodation.id, accommodation.name, accommodation_exclude.id_accommodation, accommodation_exclude.id_course

1,'acco 1',null,null
2,'acco 2',2,16
3,'acco 3',null,null
4,'acco 4',null,null

我现在的查询是这个:

SELECT *
FROM accommodations a
LEFT JOIN accommodations_exclude ae ON a.id = ae.id_accommodation 
WHERE ae.id_course = 16

但这只给了我结果集

2,'acco 2',2,16

而不是应该有空值的住宿

知道我在这里做错了什么吗?

4

5 回答 5

9

ae.id_course = 16子句从WHERE您的LEFT JOIN

SELECT *
FROM accommodations a
LEFT JOIN accommodations_exclude ae ON
    a.id = ae.id_accommodation
    AND ae.id_course = 16

您应该将其 WHERE视为最终结果集的过滤器,与链接表有关的任何内容都应该是您JOIN的 s.

您的原件WHERE ae.id_course = 16是从结果集中过滤掉 NULL ae.id_course 行。

于 2013-01-10T09:39:03.497 回答
1

使accommodations_exclude表格成为左表格,或者RIGHT JOIN像这样使用:

SELECT
 a.id, 
 a.name, 
 ae.id_accommodation, 
  ae.id_course
FROM accommodations a
RIGHT JOIN accommodations_exclude ae ON a.id = ae.id_accommodation;

SQL 小提琴演示

这会给你:

| ID |   NAME | ID_ACCOMMODATION | ID_COURSE |
----------------------------------------------
|  1 | acco 1 |           (null) |    (null) |
|  2 | acco 2 |                2 |        16 |
|  3 | acco 3 |           (null) |    (null) |
|  4 | acco 4 |           (null) |    (null) |

请注意:对于您发布的示例数据,WHERE ae.id_course = 16将只返回一行,即ae.id_course = 16.

于 2013-01-10T09:39:15.647 回答
0

“Ross McNab”的答案是最好的,但如果你没有使用条件,JOIN你可以使用这个示例代码:

SELECT *
FROM accommodations a
LEFT JOIN accommodations_exclude ae ON a.id = ae.id_accommodation 
WHERE ae.id_course = 16 OR ae.id_course IS NULL
于 2014-03-12T06:15:09.133 回答
0
SELECT ACCOMMODATION.ID, ACCOMMODATION.NAME,
       ACCOMMODATION_EXCLUDE.ID_ACCOMMODATION,
       ACCOMMODATION_EXCLUDE.ID_COURSE
  FROM ACCOMMODATION, ACCOMMODATION_EXCLUDE
 WHERE ACCOMMODATION.ID = ACCOMMODATION_EXCLUDE.ID_ACCOMMODATION(+)
       AND ACCOMMODATION_EXCLUDE.ID_COURSE = 16
于 2013-01-10T09:55:31.793 回答
0

根据您的情况,它不会再给您

WHERE ae.id_course = 16

它为您提供了正确的结果集。删除它,它将列出所有这些。

于 2013-01-10T09:38:45.623 回答