简化LEFT JOIN

时间:2015-03-27 05:39:54

标签: mysql left-join

所以我有这个问题:

  SELECT c1.field1, c2.field2
  FROM table1 c1
  LEFT JOIN table1 c2 ON c1.field1 = c2.field1 AND c1.field2 = :arg1 AND c2.field2 <> :arg1
  LEFT JOIN table2 cc ON c2.field2 = cc.field2 AND cc.field3 = :arg2
  WHERE (c2.field2 IS NULL OR cc.field2 IS NOT NULL)
  ORDER BY ISNULL(c2.field2) ASC

这有两件事:

  1. 获取给定table1.field1值的field2
  2. 获取table1.field2,其中field1与上一个点中的第一个点相同,该点也具有来自第二个表的特定属性。 (由于规范化,这只是复杂的)如果不存在则返回NULL
  3. 虽然这很有效但真的很难看。是否有更简单的版本做同样的事情?我很担心第二个JOIN需要LEFT后跟WHERE。我觉得INNER应该更简单但不起作用。

1 个答案:

答案 0 :(得分:1)

尝试将左连接转移到unioninner join,然后您可以获得这样的新查询:

SELECT c1.field1, null as field2
FROM table1 c1
  UNION ALL
SELECT c1.field1, c2.field2
FROM table1 c1
INNER JOIN table1 c2 ON c1.field1 = c2.field1 
INNER JOIN table2 cc ON c2.field2 = cc.field2 
WHERE c1.field2 = :arg1 AND c2.field2 <> :arg1 AND cc.field3 = :arg2 

首先,我将原始查询从join转移到union,方法是将where子句拆分为:

SELECT c1.field1, c2.field2
FROM table1 c1
LEFT JOIN table1 c2 ON c1.field1 = c2.field1 AND c1.field2 = :arg1 AND c2.field2 <> :arg1
WHERE (c2.field2 IS NULL )
  UNION ALL
SELECT c1.field1, c2.field2
FROM table1 c1
INNER JOIN table1 c2 ON c1.field1 = c2.field1 AND c1.field2 = :arg1 AND c2.field2 <> :arg1
LEFT JOIN table2 cc ON c2.field2 = cc.field2 AND cc.field3 = :arg2
WHERE (c2.field2 IS NOT NULL AND cc.field2 IS NOT NULL)

但是工会的第一部分可以像这样继续转移:

SELECT c1.field1, null
FROM table1 c1
WHERE c1.field2 <> :arg1 --c2.field2 must be null
  UNION ALL
SELECT c1.field1, c2.field2
FROM table1 c1
LEFT JOIN table1 c2 ON c1.field1 = c2.field1  AND c2.field2 <> :arg1
WHERE c1.field2 = :arg1 AND c2.field2 IS NULL

最后,我得到了将所有左连接转移到union和内连接的顶级查询。

我没有任何数据,所以我不确定我是对还是不对。希望它有所帮助。

相关问题