MySQL:SELECT在一个查询中来自四个不同的表

时间:2012-04-02 07:43:09

标签: php mysql sql

我有四个不同的表,一个主SPECIAL表只包含引用CONTRACTPHONE表的id。

我的查询如下:

SELECT *
FROM `specials` specials
INNER JOIN `contract` contracts
ON  specials.contract_id = contracts.id
INNER JOIN `phone` phones
ON specials.phone_id = phones.id
INNER JOIN `ugets` ugets
ON specials.id = ugets.special_id

目前,这只会从UGETS表中获得一行,但我需要使用正确的special_id来显示此特定表格中的所有行。

任何人都可以指出我正确的方向吗?我似乎无法用谷歌搜索来帮助自己。

3 个答案:

答案 0 :(得分:3)

INNER JOIN仅返回两个连接表中至少有一个匹配可用的行。问题是你要加入4个表。因此,如果您只使用ugets加入特殊内容,则可能会有更多记录(超过1),但如果您与其他表一起加入,这些记录将被过滤掉。

如果电话或合约中的每个特殊条目都没有必要存在记录,则将这两个表的连接类型更改为左连接。 (由biziclop博士评论暗示的非特异性)

通常,您应该考虑哪些联接数据是可选的,哪些是必需的。您的示例查询需要表的所有数据。也许这不是你想要的。

答案 1 :(得分:1)

您的查询看起来是正确的,除非您还想要所有行,无论是否存在contractphone。在这种情况下,您需要使用OUTER JOINLEFT JOIN代替INNER JOIN

SELECT *
FROM `specials` specials
LEFT JOIN `contract` contracts
ON  specials.contract_id = contracts.id
LEFT JOIN `phone` phones
ON specials.phone_id = phones.id
LEFT JOIN `ugets` ugets
ON specials.id = ugets.special_id

表中没有给定特殊记录的字段将返回NULL,但会显示匹配表中的所有行。

请注意,这可能会对性能产生负面影响(可能会导致在单个查询中无法获得所有四个表的好处) - 您应该评估增益与成本,并查看是否仍需要单个查询。

答案 2 :(得分:1)

作为LEFT JOINing的替代方法,您可以考虑使用UNION ALL连接三个查询的结果,每个查询将specials表连接到其他三个表中的一个。

这将确保您只为specials表上的每一行返回n(1)+ n(2)+ n(3)行,而不是n(1)* n(2)* n (3)行。