在MYSQL中加入并缺少行

时间:2010-07-16 19:07:18

标签: sql mysql join

我有一个像这样的查询:

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),我都希望这样。我怎样才能做到这一点? (有办法吗?)

3 个答案:

答案 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所解释的那样,你在寻找一个外部联盟。

Joins Tuturial