简体   繁体   中英

SQL - how to select all rows between two tables with relations,

First of all, I'm sorry with my bad english.

I wanted to select all row in this two table ( Company and Contacts ), but when there's a related data between two tables then display as 1 rows.

Table Company:

+---------+-----------+----------+
| cmpy_id | Company   | Cntct_id |
+---------+-----------+----------+
| 1       | Company 1 |   1      |
| 2       | Company 2 |          | 
| 3       | Company 3 |          |
+---------+-----------+----------+

Table Contacts:

+----------+-----------+
| Cntct_id | Contact   |
+----------+-----------+
| 1        | Contact 1 |
| 2        | Contact 2 |
| 3        | Contact 3 |
+----------+-----------+

Result I need:

+-----------+------------+
| Contact   |  Company   |
+-----------+------------+
| Contact 1 |  Company 1 |
| Contact 2 |            | 
| Contact 3 |            |
|           |  Company 2 |
|           |  Company 3 |
+-----------+------------+

How can i achieve that result?

You can phrase this as a union between a left and right join:

SELECT
    Contact, Company
FROM
(
    SELECT t1.Contact, t2.Company, 1 AS position
    FROM Contacts t1
    LEFT JOIN Company t2
        ON t1.Cntct_id = t2.Cntct_id
    UNION ALL
    SELECT t1.Contact, t2.Company, 2 AS position
    FROM Contacts t1
    RIGHT JOIN Company t2
        ON t1.Cntct_id = t2.Cntct_id
    WHERE t1.Contact IS NULL
) t
ORDER BY
   position, Contact, Company;

在此处输入图片说明

Demo

SELECT Contact,Company 
FROM Contacts contact
LEFT JOIN Company company ON company.Cntct_id=contact.Cntct_id 
UNION 
SELECT Contact,Company 
FROM Contacts contact
RIGHT JOIN Company company ON company.Cntct_id=contact.Cntct_id;

Explanation: First LEFT JOIN would get us all the records from the left table(Table:Contacts) regardless of whether or not they have a match in the right table(Table : Company), like this:

SELECT Contact,Company  
FROM Contacts contact 
LEFT JOIN Company company ON company.Cntct_id=contact.Cntct_id;

Contact     Company
==============================
Contact 1   Company 1
Contact 2   NULL
Contact 3   NULL

Then the second RIGHT JOIN would get us all the records from the right table(Table : Company) regardless of whether or not they have a match in the left table(Table:Contacts), like this:

SELECT Contact,Company  
FROM Contacts contact 
RIGHT JOIN Company company ON company.Cntct_id=contact.Cntct_id;

Contact     Company
==============================
Contact 1   Company 1
NULL        Company 2
NULL        Company 3

Finally the UNION - "run both of these queries, then stack the results on top of each other"; some of the rows will come from the first query and some from the second.

SELECT Contact,Company  
FROM Contacts contact LEFT JOIN Company company ON company.Cntct_id=contact.Cntct_id 
UNION 
SELECT Contact,Company 
FROM Contacts contact RIGHT JOIN Company company ON company.Cntct_id=contact.Cntct_id;

Contact     Company
==============================
Contact 1   Company 1
Contact 2   NULL
Contact 3   NULL
NULL        Company 2
NULL        Company 3

Note:If you use UNION ALL instead of UNION,it will list out duplicates.

Contact     Company
==============================
Contact 1   Company 1
Contact 2   NULL
Contact 3   NULL
Contact 1   Company 1
NULL        Company 2
NULL        Company 3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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