如何在不对表中的不同值重复相同的行的情况下联接两个表

时间:2019-02-19 08:41:37

标签: sql db2

第一张桌子:

+ ---+-----------+
| 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 |
+ -----------+---------------+-------+

3 个答案:

答案 0 :(得分:1)

在这里,您可以分别使用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
---------------------------------

答案 1 :(得分:1)

使用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起,...)中都可用。

答案 2 :(得分:0)

如果您使用的是let mostPositives(l: int list) : int list= let counter = ref 0 in let maxSize = ref 0 in for i = 0 to List.length(l) -1 do if (List.nth l i) >= 0 then counter := !counter + 1 else counter := 1; maxSize := (max !counter !maxSize ); done; ,可以尝试以下操作。

SQL Server

Online Demo

输出

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

MySQL db-fiddle