我有四个不同的表,一个主SPECIAL
表只包含引用CONTRACT
和PHONE
表的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
来显示此特定表格中的所有行。
任何人都可以指出我正确的方向吗?我似乎无法用谷歌搜索来帮助自己。
答案 0 :(得分:3)
INNER JOIN仅返回两个连接表中至少有一个匹配可用的行。问题是你要加入4个表。因此,如果您只使用ugets加入特殊内容,则可能会有更多记录(超过1),但如果您与其他表一起加入,这些记录将被过滤掉。
如果电话或合约中的每个特殊条目都没有必要存在记录,则将这两个表的连接类型更改为左连接。 (由biziclop博士评论暗示的非特异性)
通常,您应该考虑哪些联接数据是可选的,哪些是必需的。您的示例查询需要表的所有数据。也许这不是你想要的。
答案 1 :(得分:1)
您的查询看起来是正确的,除非您还想要所有行,无论是否存在contract
或phone
。在这种情况下,您需要使用OUTER JOIN
或LEFT 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)行。