2012-04-02 74 views
1

我有四个不同的表,一个主要SPECIAL表只包含参照CONTRACTPHONE表的id。MySQL:在一个查询中选择来自四个不同表的结果

我的查询如下所示:

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

如果您发出更简单的查询,会发生什么情况 - 在specials.id = ugets.special_id中选择特殊内部连接ugets?你有多少行?尽量不要使用'select *',特别是对于多表连接。 – 2012-04-02 07:45:37

+0

'LEFT JOIN'而不是'INNER JOIN'? – biziclop 2012-04-02 07:46:02

+0

请抽取数据集? – Romain 2012-04-02 07:53:40

回答

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返回一个记录表,但表中的所有行,其中有一个比赛将显示。

请注意,这可能会对性能产生不利影响(可能会导致在单个查询中获取所有四张表的好处) - 您应该评估收益与成本,并确定您是否仍想要单个查询。

+0

谢谢你,这可以工作,但它会为'ugets'和'special_id'的两个实例返回多行。我意识到这是LEFT JOIN应该做的事情,但是有没有办法返回多行,而只是返回同一行中的两个'ugets'实例的数组值呢? – 2012-04-02 11:05:18

+1

看起来你试图让SQL像Turing完全语言一样行事。有些东西在应用程序代码中更好,而不是DB端。你可以使用'GROUP_CONCAT'来实现你想要的,但是我会反对它(不可移植,...)。 – Romain 2012-04-02 11:33:16

+0

我选择运行一个单独的函数来稍后在我的脚本中检索值。感谢您的建议。 – 2012-04-07 14:49:49

3

INNER JOIN只返回两个连接表中至少有一个匹配项可用的行。问题在于你将4个表连接在一起。因此,如果您仅通过ugets加入特价商品,则可能会有更多记录(超过1个),但如果您加入其他表格,则会将这些记录过滤掉。

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

一般来说,您应该考虑哪些加入的数据是可选的,哪些是必需的。您的示例查询需要您的表的所有数据。也许这不是你想要的。

+0

所以,我收集,如果INNER JOIN在'SPECIAL'表中有相同的'special_id'对应'id',那么INNER JOIN将不会从'UGET'返回两行或更多行。 – 2012-04-02 10:53:16

+0

如果只有内部加入SPECIAL和UGET,那么您应该根据您的加入条件接收SPECIAL和UGET中所有可能的记录组合。这意味着UGET中具有相同字段值special_id的记录将导致结果集中的单独记录。如果你希望它们仅限于SPECIALS中每个special_id的一个连接,那么你必须对你的记录进行分组(这将限制你的可选列到分组或集合的列),或者你确定一个在子查询中具有这个special_id的UGET ID并添加一个条件以匹配该ID。 – TRD 2012-04-02 11:35:56

1

作为LEFT JOINing的替代方案,您可以考虑使用UNION ALL加入三个查询的结果,每个查询的内部结合specials表与其他三个表中的一个。

这将确保您只返回n(1)+ n(2)+ n(3)行。

相关问题