如何删除不必要的join,更新where条件

时间:2011-11-24 17:12:11

标签: mysql sql

我在MySql数据库中有三个表,我正在查询中加入id / value对。

   |    A     |       B      |     C         |
   | -------- |--------------|---------------|
   |   id     |  id          |  id           |
   |   name   |  fooId       |  attributeId  |
   |   desc   |  value       |  displayIndex |
   |   ...    |  attributeId |  ...          |

我现在拥有的是:

SELECT C.id, B.value
  FROM  A, B, C
  WHERE A.id = B.attributeId
    AND A.id = C.attributeId
    AND B.fooId = 25
  ORDER BY C.displayIndex

所以基本上我们通过A加入B和C.过去,C表中的一个条目必须在A表中有一个相应的(父)条目。但是,情况将不再如此。 C表仍将由A表主要控制,但是,有些情况下我们需要在C表中单独(永远在线)输入。

修改

我想要来自B和C的所有记录在attributeId上匹配,但我也想要任何记录,其中C.attributeId = -1。有人可以帮我解决这个问题需要做什么吗?

编辑#2

根据你们提出的反馈和建议以及一些谷歌搜索,我现在有了这个:

(SELECT C.id, B.value, C.displayIndex
  FROM  B, C
  WHERE B.attributeId = C.attributeId
    AND B.fooId = 25)

UNION

(SELECT C.id, null, C.displayIndex
  FROM C
  WHERE C.attributeId = -1)

ORDER BY 3

有什么更好的做法吗? UNION有什么问题吗?

2 个答案:

答案 0 :(得分:5)

我已经更新了我的答案,以解决OP的编辑问题。

这将返回所有记录where the attributeId for tables B and C match
B.fooId = 25, OR C.attributeId = -1
C.attributeId = -1且表B中没有匹配时,将返回NULL代替B.Value,根据OP中的Edit #2似乎可以接受{/ 1}} p>

SELECT C.Id, B.Value, C.displayIndex
FROM C 
LEFT JOIN B ON C.attributeId = B.attributeId
WHERE B.fooId = 25
   OR C.attributeId = -1
ORDER BY C.DisplayIndex ASC

答案 1 :(得分:0)

你可能正在购买笛卡尔积。

就像亚当·温格所说,你需要内心加入他们。当所有连接表中至少有一个匹配时,内连接将返回行。

如果您需要确保结果也在表A中,那么您也需要加入该结果:

SELECT c.Id, b.Value
FROM B 
INNER JOIN A ON B.attributeId = A.ID
INNER JOIN C ON B.attributeId = C.attributeId
WHERE B.fooId = 25
   AND C.attributeId = -1
ORDER BY C.DisplayIndex