简体   繁体   English

MySQL:在一个查询中从四个不同表中选择结果

[英]MySQL : SELECT results from four different tables in one query

I have four different tables, one main SPECIAL table containing only id's that reference to the CONTRACT and PHONE tables. 我有四个不同的表,一个主要的SPECIAL表只包含引用CONTRACTPHONE表的ID。

My query looks as follows: 我的查询如下所示:

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

At the moment, this only gets ONE row from the UGETS table, but I need all rows from this specific table with the correct special_id . 目前,这仅从UGETS表中获得一行,但是我需要此特定表中的所有行都具有正确的special_id

Can anyone please point me in the correct direction? 谁能给我指出正确的方向? I can't seem to help myself with Googling it. 我似乎无法帮助自己进行Google搜索。

INNER JOIN only returns rows where at least one match in both joined tables is available. INNER JOIN仅返回两个连接表中至少有一个匹配项可用的行。 The problem is that you are joining 4 tables together. 问题是您要将4个表连接在一起。 So there could be more records (than 1) if you join only specials with ugets but these records get filtered out if you join with your other tables. 因此,如果仅将特殊内容与ugets联接,则可能会有更多记录(超过1条),但是如果与其他表联接,则这些记录将被过滤掉。

If it is not necessary that there is an existing record for every specials-entry in phones or contracts then change the joining type for these 2 tables to left join. 如果不需要电话或合同中每个特殊条目的现有记录,则将这两个表的联接类型更改为左联接。 (as unspecific hinted by comment of Dr. biziclop) (如biziclop博士的评论所暗示的未明确)

In general you should consider which of your joined data is optional and which is required. 通常,您应该考虑哪些联接数据是可选的,哪些是必需的。 Your example query requires all data of your tables. 您的示例查询需要表的所有数据。 Maybe this is not what you intended. 也许这不是您想要的。

Your query looks about right, unless you also want all rows, regardless of the existence of a contract or phone . 您的查询看起来正确,除非您也希望所有行,无论是否存在contractphone In this case, you'll want to use OUTER JOIN or LEFT JOIN instead of INNER JOIN : 在这种情况下,您将要使用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

Fields from tables where there are not records for a given special will be returned with NULL , but all rows from tables where there's a match will be shown. 没有给定特殊记录的表中的字段将返回NULL ,但是将显示匹配项中表的所有行。

Beware this could have adverse performance impacts (possibly to the extent it voids the benefits of getting all four tables in a single query) - you should evaluate the gains vs. costs and see if you still want a single query. 请注意,这可能会对性能产生不利影响(可能在一定程度上丧失了在单个查询中获取所有四个表的好处)-您应该评估收益与成本的关系,并查看是否仍需要单个查询。

As an alternative to LEFT JOINing, you could consider using UNION ALL to join the results of three queries, each inner joining the specials table to one of the other three tables. 作为LEFT JOINing的替代方法,您可以考虑使用UNION ALL来连接三个查询的结果,每个内部将specials表连接到其他三个表之一。

This will ensure that you only return n(1)+n(2)+n(3) rows for each row on the specials table, instead of n(1)*n(2)*n(3) rows. 这将确保您只对specials表上的每一行返回n(1)+ n(2)+ n(3)行,而不是n(1)* n(2)* n(3)行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM