我有一个像这样的查询:
SELECT DISTINCT
`a`.*,
`b`.*,
`c`.*
FROM `a`
INNER JOIN `b` ON (`b`.`a_id` = `a`.`id` )
INNER JOIN `c` ON (`c`.`id` = `b`.`c_id`)
WHERE (
(`a`.`id` = 12345) AND
(`b`.`foo`= "bar")
)
基本上,这将从a = id = 12345的行中获取行,并且b中涉及此行的行以及来自c的行关于此b行,仅b中的行具有foo = bar
现在,如果没有b行有foo = bar,则甚至不返回a行。这是错的。无论匹配哪一行返回(无论是否有bs和cs),我都希望这样。我怎样才能做到这一点? (有办法吗?)
答案 0 :(得分:6)
我认为你应该查看如何进行OUTER JOINS。听起来这可能就是你所要求的。
类似的东西:
SELECT DISTINCT
`a`.*,
`b`.*,
`c`.*
FROM `a`
LEFT OUTER JOIN
`b` ON `b`.`a_id` = `a`.`id`
LEFT OUTER JOIN
`c` ON `c`.`id` = `b`.`c_id`
WHERE
`a`.`id` = 12345
编辑:使用新信息(b上的条件,必须有一个列foo = bar。这在b中根本没有行时有效。但是如果有一个foo = notbar,我希望它还有一个),试试这个。注意:我删除了抽搐,以便于阅读和查看引号。
SELECT DISTINCT
a.*,
b.*,
c.*
FROM a
LEFT OUTER JOIN
b ON b.a_id = a.id and b.foo = 'bar'
LEFT OUTER JOIN
c ON c.id = b.c_id
WHERE
a.id = 12345
答案 1 :(得分:1)
正如MJB所说,您需要使用外部联接,因此当a
中没有匹配的行时,会包含b
行。
如果要将b
的匹配行限制为与其他条件匹配的行,则需要将这些条件放入b
的JOIN表达式中。如果在WHERE子句中保留b
的条件,则会排除由于外部联接而b
列为NULL的联接行。
SELECT DISTINCT
`a`.*,
`b`.*,
`c`.*
FROM `a`
LEFT OUTER JOIN (`b` INNER JOIN `c` ON (`c`.`id` = `b`.`c_id`))
ON (`b`.`a_id` = `a`.`id` AND `b`.`foo` = 'bar')
WHERE `a`.`id` = 12345
注意我在将外部联接评估为c
之前使用括号将b
加入a
。
另外,我建议对单词引号使用单引号,而不是双引号。只是为了养成尽可能使用标准SQL的习惯,而不是特定于MySQL的语法。
答案 2 :(得分:0)
正如MJB所解释的那样,你在寻找一个外部联盟。