完全外连接mysql中的多个表

时间:2014-06-18 15:17:09

标签: php mysql sql join full-outer-join

我被困在一个查询中..我想显示客户的所有产品以及系统在1个网格/行中收到的所有短信。我可以实现这一点,但事情是只显示客户产品我需要3 4其他表加入并显示所有数据,如产品型号,客户名称等。其他的东西来自其他表..所以我需要2表做外部联接,并显示4 5个表中的数据。我试过但我失败了。

Select      tcp.*
            , concat(tc.firstname,' ',tc.lastname)  as cust_id
            , tc.mobile
            , tb.brand_name                         as brand
            , tgt.gadget_type                       as gadget_type
            , tm.model_name                         as model
            , ttt.ticket_type                       as ticket_type
            , trs.registration_source               as registration_source 
From        tbl_cust_products                       tcp  
Left Join   `tbl_received_sms`                      trsm    on  tcp.id = trsm.cust_prod_id 
Left Join   tbl_customer                            tc      on  tcp.cust_id=tc.id 
Left Join   tbl_brand                               tb      on  tcp.brand = tb.id 
Left Join   tbl_gadget_type                         tgt     on  tcp.gadget_type=tgt.id 
Left Join   tbl_model                               tm      on  tcp.model = tm.id 
Left Join   tbl_ticket_type                         ttt     on  tcp.ticket_type=ttt.id 
Left Join   tbl_registration_source                 trs     on  trs.id=tcp.registration_source 
Where       tcp.del_date is NULL 
Union 
Select      tcp.*
            , concat(tc.firstname,' ',tc.lastname)  as cust_id
            , tc.mobile
            , tb.brand_name                         as brand
            , tgt.gadget_type                       as gadget_type
            , tm.model_name                         as model
            , ttt.ticket_type                       as ticket_type
            , trs.registration_source               as registration_source 
From        tbl_cust_products                       tcp  
Right Join  `tbl_received_sms`                      trsm    on  tcp.id=trsm.cust_prod_id 
Left Join   tbl_customer                            tc      on  tcp.cust_id=tc.id 
Left Join   tbl_brand                               tb      on  tcp.brand=tb.id 
Left Join   tbl_gadget_type                         tgt     on  tcp.gadget_type=tgt.id 
Left Join   tbl_model                               tm      on  tcp.model = tm.id 
Left Join   tbl_ticket_type                         ttt     on  tcp.ticket_type=ttt.id 
Left Join   tbl_registration_source                 trs     on  trs.id=tcp.registration_source 
Where       tcp.del_date is NULL
上面的

我只想在tbl_cust_productstbl_received_sms表上进行外连接。我在这里尝试了outer join的联盟。当我搜索并发现MySql do not support direct outer join和其他大数据库处理程序一样。

如果我犯了任何错误使用联合或任何逻辑plz帮助我实现这一点..

EDITED 问题: 在tbl_received_sms中有7,734条记录,在tbl_cust_products中有3条记录..所以我需要总共7737条记录。如果我使用UNION,则只能获得3条记录,如果我使用UNION ALL,则会获得7737条记录,但所有记录的所有字段均为NULL

1 个答案:

答案 0 :(得分:0)

问题是您的查询返回表tcp(tb​​l_cust_products),tc(tbl_customer),tb(tbl_brand),tgt(tbl_gadget_type),tm(tbl_model),ttt(tbl_ticket_type)和trs(tbl_registration_source)中的列。 / p>

所有这些列都依赖于tcp(tb​​l_cust_products)表中存在的记录,因为它们来自此表或来自LEFT OUTER JOIN到此表中记录的表。

第一个查询将返回在tcp(tb​​l_cust_products)上具有匹配记录的任何行。第二个查询也将返回任何在trsm(tbl_received_sms)上具有匹配记录的查询。但是,两者返回的任何内容都会被UNION消除。

进一步的问题是,从tcp(tb​​l_cust_products)上没有匹配记录的第二个查询返回的任何行在查询的一部分返回的所有字段中都将为NULL(因为所有字段都依赖于匹配在tcp(tb​​l_cust_products)上。然后UNION将消除除了其中一行之外的所有行,因为它消除了重复,并且所有行都是相同的(即,所有NULL)。

如果要从中获取输出,请将trsm(tbl_received_sms)中的列添加到返回的列中。可能trsm.cust_prod_id是一个很好的尝试。

编辑更多细节来解释工会。

以查询的大幅简化版本为例: -

SELECT tcp.id,
    tc.name
FROM        tbl_cust_products                       tcp  
LEFT JOIN   tbl_received_sms                      trsm    ON  tcp.id = trsm.cust_prod_id 
LEFT JOIN   tbl_customer                            tc      ON  tcp.cust_id=tc.id 
UNION
SELECT tcp.id,
    CONCAT(tc.firstname,' ',tc.lastname)  as cust_id
FROM        tbl_cust_products                       tcp  
RIGHT JOIN   tbl_received_sms                      trsm    ON  tcp.id = trsm.cust_prod_id 
LEFT JOIN   tbl_customer                            tc      ON  tcp.cust_id=tc.id 

假设表格包含以下内容

tbl_cust_products
id  name    cust_id
1   a   5
2   b   6

tbl_received_sms
id  cust_prod_id    data
3   2       c
4   3       d
5   4       e

tbl_customer
id  name
5   fred
6   burt

第一个查询将从tbl_cust_products返回两个记录,其中一个记录与tbl_received_sms匹配: -

id  name
1   fred
2   burt

第二个查询将从tbl_received_sms中找到3条记录,其中一条记录与tbl_cust_products匹配。两个不匹配的记录在返回的字段中都是NULL(因为在tbl_cust_products上没有匹配的记录,该字段的值为null,而tbl_customer中的字段值与tbl_cust_products的非存在记录相匹配)。将填充匹配的记录: -

id      name
NULL    NULL
NULL    NULL
2       burt

UNION将这两个地段合并在一起,

id      name
1       fred
2       burt
NULL    NULL
NULL    NULL
2       burt

但消除了重复,因此: -

id      name
1       fred
2       burt
NULL    NULL