簡體   English   中英

如何在不對表中的不同值重復相同的行的情況下聯接兩個表

[英]How to join two tables without repeating the same rows for different values in table

第一表:

+ ---+-----------+
| id | country   |
+ ---+-----------+
| 1  | India     |
| 2  | Australia |
| 3  | Canada    |
| 4  | France    |
| 5  | Russia    |
+ ---+-----------+

第二張表:

+ ---+-------+------------+
| id | user  | country_id |
+ ---+-------+------------+
| 1  | Ojas  | 1          |
| 2  | Raj   | 1          |
| 3  | John  | 3          |
| 4  | Robin | 2          |
| 5  | Mary  | 5          |
| 6  | Kamal | 4          |
| 7  | Bipin | 5          |
| 8  | Rohit | 1          |
+ ---+-------+------------+

預期結果:

+ -----------+---------------+-------+
| country_id | country       | user  |
+ -----------+---------------+-------+
| 1          | India         | Ojas  |
| null       | null          | Raj   |
| null       | null          | Rohit |
| 2          | Australia     | Robin |
| 3          | Canada        | John  |
| 4          | France        | Kamal |
| 5          | Russia        | Mary  |
| null       | null          | Bipin |
+ -----------+---------------+-------+

在這里,您可以分別使用mysql和PostgreSql GROUP_CONCAT的聚合方法以及string_agg(some_column,',')方法將名稱與逗號連接起來,從而得到每個國家1條記錄。

對於MySQL

SELECT countries.id AS Id, countries.name AS Country, GROUP_CONCAT(DISTINCT users.name) as Users
FROM countries
INNER JOIN users ON users.country_id = countries.id
GROUP BY countries.id;

對於PostgreSQL

SELECT countries.id AS Id, countries.name AS Country, string_agg(users.name, ',') as Users
FROM countries
INNER JOIN users ON users.country_id = countries.id
GROUP BY countries.id;

它將產生如下結果

Id | Country     | User
---------------------------------
1  | India       | Ojas,Raj,Rohit
2  | Australia   | Robin
3  | Canada      | John
4  | France      | Kamal
5  | Russia      | Mary,Bipin
---------------------------------

使用LAG查看上一行是否包含相同的國家。

select
  case when lag(c.id) over (order by c.id, u.user) = c.id then null else c.id end
    as country_id,
  case when lag(c.id) over (order by c.id, u.user) = c.id then null else c.country end
    as country,
  u.user
from countries c
join users u on u.country_id = c.id
order by c.id, u.user;

LAG是標准SQL,因此在許多DBMS(Oracle,PostgreSQL,SQL Server,MySQL自版本8起,...)中可用。

如果您使用的是SQL Server ,則可以嘗試如下操作。

SELECT c.id AS country_id, 
       c.country, 
       t.[user] 
FROM   (SELECT s.country_id, 
               s.[user], 
               Row_number() 
                 OVER ( 
                   partition BY s.country_id 
                   ORDER BY s.id) rn 
        FROM   @second s) t 
       LEFT JOIN @country c 
              ON t.country_id = c.id 
                 AND t.rn = 1 

在線演示

輸出量

+------------+-----------+-------+
| country_id | country   | user  |
+------------+-----------+-------+
| 1          | India     | Ojas  |
+------------+-----------+-------+
| NULL       | NULL      | Raj   |
+------------+-----------+-------+
| NULL       | NULL      | Rohit |
+------------+-----------+-------+
| 2          | Australia | Robin |
+------------+-----------+-------+
| 3          | Canada    | John  |
+------------+-----------+-------+
| 4          | France    | Kamal |
+------------+-----------+-------+
| 5          | Russia    | Mary  |
+------------+-----------+-------+
| NULL       | NULL      | Bipin |
+------------+-----------+-------+

對於其他數據庫:

可以不使用ROW_NUMBER()編寫相同的查詢,如下所示,這樣它就可以在其他數據庫(如mysql

SELECT c.id AS country_id, 
       c.country, 
       t.user 
FROM   (SELECT s.country_id, 
               s.user, 
               s.id,
               CASE 
                 WHEN (SELECT Min(id) 
                       FROM   second s2 
                       WHERE  s2.country_id = s.country_id) = s.id THEN 1 
                 ELSE 0 
               END rn 
        FROM   second s) t 
       LEFT JOIN country c 
              ON t.country_id = c.id 
                 AND t.rn = 1 
ORDER  BY t.country_id ,t.id

MySQL數據庫提琴

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM