与mysql的条件连接

时间:2014-04-16 20:56:00

标签: jquery mysql conditional

我有3张桌子:

ONE (ID - TYPE)

TWO (ID - FIELDa)

THREE (ID - FIELDb)

如果ONE.TYPE = 0我将ONETWO加入,否则如果ONE.TYPE = 1加入THREE

如何使用所有记录执行单个连接选择查询?

结果:

TYPE - RESULT (FIELDa or FIELDb)

我写这个:

SELECT `m`.`meal_name`,
                        `m`.`short`,
                        `m`.`id`,
                        `m`.`time`,
                        `m`.`budget`,
                        `p`.`filename`,
                        `t`.`type`,

        CASE `m`.`author_type`
       WHEN 0 THEN `a`.`author`
       WHEN 1 THEN `u`.`first_name`
       ELSE NULL
       END AS autore

FROM                    
                        `photos` p,
                        `types` t,
                        `meals` m                      
LEFT JOIN `authors` a
              ON  `m`.`author_type`=0 AND (`m`.`id` = `a`.`id` )
LEFT JOIN `users` u         
              ON `m`.`author_type`=1 AND (`m`.`id` = `u`.`user_id`  )

WHERE 
    `m`.`type` = `t`.`id`
    AND
    `m`.`id` = `p`.`id`

但它只返回了一些记录,其中author_type = 0 ....任何想法?

谢谢。

2 个答案:

答案 0 :(得分:1)

您可以在每个LEFT JOIN中使用ONE.TYPE的相应条件执行两个SELECT,并在最终COALESCE()列表中使用LEFT JOIN在非空值之间进行选择SELECT ONE.ID, TYPE, /* The LEFT JOINs will return NULL for one of these. Use COALESCE() to get the non-null result If neither matches, NULL is returned */ COALESCE(TWO.Fielda, THREE.FIELDb) AS RESULT FROM ONE LEFT JOIN TWO ON (ONE.TYPE = 0 AND ONE.ID = TWO.ID) LEFT JOIN THREE ON (ONE.TYPE = 1 AND ONE.ID = THREE.ID) 返回的值:

FROM

合并您添加的完整查询:

您不应该将隐式连接与显式连接混合使用,实际上您根本不应该使用旧式隐式连接(LEFT JOIN子句中的逗号分隔表)。将它们转换为显式SELECT `m`.`meal_name`, `m`.`short`, `m`.`id`, `m`.`time`, `m`.`budget`, `p`.`filename`, `t`.`type`, COALESCE(a.author, u.firstname) AS autore FROM /* Replace all the implicit joins */ meals m LEFT JOIN photos p ON m.id = p.id LEFT JOIN type t ON m.t LEFT JOIN `authors` a ON `m`.`author_type`=0 AND (`m`.`id` = `a`.`id` ) LEFT JOIN `users` u ON `m`.`author_type`=1 AND (`m`.`id` = `u`.`user_id` )ype = t.id /* No WHERE clause join conditions remain, they are in the ON clauses instead...*/ s:

{{1}}

答案 1 :(得分:1)

您不清楚您为JOIN匹配哪些列。

以下是一种做出"条件"的方法的例子。加入:

SELECT one.id
     , one.type
     , CASE one.type
       WHEN 0 THEN two.field
       WHEN 1 THEN tee.field
       ELSE NULL
       END AS field
  FROM one
  LEFT 
  JOIN two
    ON one.type = 0
   AND two.id = one.id
  LEFT 
  JOIN three tee
    ON one.type = 1
   AND tee.id = one.id

要将结果集仅限制为仅包含"匹配"的行,我们会添加

WHERE two.id IS NOT NULL
   OR tee.id IS NOT NULL

更新的答案(基于更新的问题)

两个最可能的解释是"只有一些行"是

1)查询中的JOIN谓词过滤掉了在另一个表中找不到匹配项的行

2)JOIN谓词是在不匹配"的列上指定的。 (例如,与users.user_id列匹配的meals.id列让我们感到有点奇怪。)

如果要从meals返回所有行,是否在任何其他表(photostypes)中都有匹配的行,则使用OUTER JOIN操作,以meals作为驾驶表。

例如:

 SELECT m.meal_name
      , m.short
      , m.id
      , m.time
      , m.budget
      , p.filename
      , t.type
      , CASE m.author_type
        WHEN 0 THEN a.author
        WHEN 1 THEN u.first_name
        ELSE NULL
        END AS autore
  FROM meals m
  LEFT
  JOIN types t
       ON t.id = m.type
  LEFT
  JOIN photos p
       ON p.id = m.id
  LEFT
  JOIN authors a
       ON m.author_type=0 
       AND m.id = a.id
  LEFT
  JOIN users u
       ON m.author_type=1
       AND m.id = u.user_id

请注意,我们更喜欢避免连接操作的旧式逗号语法。我们更喜欢使用JOIN关键字代替逗号,我们更喜欢JOIN谓词位于ON子句中,而不是WHERE子句。

上面的查询将返回来自用餐的每一行,以及每个表中的匹配行。

再次,连接谓词将我们视为有点奇怪。例如,与来自id的{​​{1}}列匹配的meals user_id列似乎有点奇怪。通常,我们看到在一个表中的外键与另一个表中的主键之间进行匹配。 (但我们没有看到表格架构或任何样本数据,所以这可能是有效的。它看起来很奇怪。)