sql - 匹配不同列位置中的两个相同值
sql - match two of the same values in different column positions
我希望在 id 上加入两个不同的 table,并且需要从每个 table 中提取唯一名称;如果一个 table 有特定名称而另一个没有,则应该有一个值和一个空值。反之亦然。
使用联接,当前输出如下所示:
id name_1 name_2
1 max steph
1 max john
1 john chris
1 john chris
1 chris steph
1 chris null
1 null max
1 null null
1 tony john
1 tony max
预期输出:
id name_1 name_2
1 max max
1 john john
1 chris chris
1 null steph
1 tony null
当前 sql:
select
table1.id,
table1.name as name_1,
table2.name as name_2
from table1
left join table2
on table1.id = table2.id
(雪花)
以下内容可用于此 -
with cte as
(
select distinct t1.id,name_1 from t1)
select distinct ifnull(t2.id,cte.id) id,
cte.name_1,
t2.name_2
from t2 full outer join cte
ON cte.id=t2.id
and cte.name_1 = t2.name_2
order by cte.name_1;
+----+--------+--------+
| ID | NAME_1 | NAME_2 |
|----+--------+--------|
| 1 | chris | chris |
| 1 | john | john |
| 1 | max | max |
| 1 | tony | NULL |
| 1 | NULL | steph |
+----+--------+--------+
添加 WHERE 子句。
select
table1.id,
table1.name as name_1,
table2.name as name_2
from table1
left join table2
WHERE table1.name = table2.name
OR table1.name is null
OR table2.name is null
on table1.id = table2.id
如果您只需要一个唯一名称列表
select distinct name from table1
union
select distinct name from table2
SELECT
NVL(d1.id, d2.id) as id,
d1.name as name_1,
d2.name as name_2
FROM (
SELECT DISTINCT id,name FROM table1
) AS d1
FULL OUTER JOIN (
SELECT DISTINCT id,name FROM table2
) AS d2
ON d1.id = d2.id AND d1.name = d2.name
ORDER BY 1, (d1.name,d2.name)
这从两个 table 中获取不同的 id、name 对,然后完全外部连接这些值集。因此,如果 id,name 在两者中都匹配。如果它们不匹配,它们仍然会保留。
所以这些 CTE 提供了假数据:
WITH table1(id,name) AS (
select * from values (1,'aa'),(1,'ab'),(2,'ba')
), table2(id,name) AS (
select * from values (1,'aa'),(1,'ac'),(2,'ba'),(2,'bb')
)
ID
NAME_1
NAME_2
1
aa
aa
1
ab
null
1
null
ac
2
ba
ba
2
null
bb
西蒙斯的回答是必经之路,因为 snowflake
支持 full outer joins
。但是对于那些使用不支持完全外部连接的关系数据库并且有同样问题的人来说,这种方法可以作为替代方法:
select id,
if(instr(group_concat(tb), 1), name, NULL) name_1,
if(instr(group_concat(tb), 2), name, NULL) name_2
from(
select id, name, 1 tb from table1
union
select id, name, 2 tb from table2
) a
group by id, name
order by name
结果:
| id | name_1 | name_2 |
| --- | ------ | ------ |
| 1 | chris | chris |
| 1 | john | john |
| 1 | max | max |
| 1 | null | steph |
| 1 | tony | null |
假数据:
CREATE TABLE table1 (
id int(11),
name varchar(50)
);
CREATE TABLE table2 (
id int(11),
name varchar(50)
);
INSERT INTO table1 VALUES
(1, 'max'),
(1, 'john'),
(1, 'chris'),
(1, 'tony');
INSERT INTO table2 VALUES
(1, 'steph'),
(1, 'john'),
(1, 'chris'),
(1, 'max');
还有一个 dbfiddle:https://www.db-fiddle.com/f/gQ4U7hu2S2EyFEtZrapqdu/6
我希望在 id 上加入两个不同的 table,并且需要从每个 table 中提取唯一名称;如果一个 table 有特定名称而另一个没有,则应该有一个值和一个空值。反之亦然。
使用联接,当前输出如下所示:
id name_1 name_2
1 max steph
1 max john
1 john chris
1 john chris
1 chris steph
1 chris null
1 null max
1 null null
1 tony john
1 tony max
预期输出:
id name_1 name_2
1 max max
1 john john
1 chris chris
1 null steph
1 tony null
当前 sql:
select
table1.id,
table1.name as name_1,
table2.name as name_2
from table1
left join table2
on table1.id = table2.id
(雪花)
以下内容可用于此 -
with cte as
(
select distinct t1.id,name_1 from t1)
select distinct ifnull(t2.id,cte.id) id,
cte.name_1,
t2.name_2
from t2 full outer join cte
ON cte.id=t2.id
and cte.name_1 = t2.name_2
order by cte.name_1;
+----+--------+--------+
| ID | NAME_1 | NAME_2 |
|----+--------+--------|
| 1 | chris | chris |
| 1 | john | john |
| 1 | max | max |
| 1 | tony | NULL |
| 1 | NULL | steph |
+----+--------+--------+
添加 WHERE 子句。
select
table1.id,
table1.name as name_1,
table2.name as name_2
from table1
left join table2
WHERE table1.name = table2.name
OR table1.name is null
OR table2.name is null
on table1.id = table2.id
如果您只需要一个唯一名称列表
select distinct name from table1
union
select distinct name from table2
SELECT
NVL(d1.id, d2.id) as id,
d1.name as name_1,
d2.name as name_2
FROM (
SELECT DISTINCT id,name FROM table1
) AS d1
FULL OUTER JOIN (
SELECT DISTINCT id,name FROM table2
) AS d2
ON d1.id = d2.id AND d1.name = d2.name
ORDER BY 1, (d1.name,d2.name)
这从两个 table 中获取不同的 id、name 对,然后完全外部连接这些值集。因此,如果 id,name 在两者中都匹配。如果它们不匹配,它们仍然会保留。
所以这些 CTE 提供了假数据:
WITH table1(id,name) AS (
select * from values (1,'aa'),(1,'ab'),(2,'ba')
), table2(id,name) AS (
select * from values (1,'aa'),(1,'ac'),(2,'ba'),(2,'bb')
)
ID | NAME_1 | NAME_2 |
---|---|---|
1 | aa | aa |
1 | ab | null |
1 | null | ac |
2 | ba | ba |
2 | null | bb |
西蒙斯的回答是必经之路,因为 snowflake
支持 full outer joins
。但是对于那些使用不支持完全外部连接的关系数据库并且有同样问题的人来说,这种方法可以作为替代方法:
select id,
if(instr(group_concat(tb), 1), name, NULL) name_1,
if(instr(group_concat(tb), 2), name, NULL) name_2
from(
select id, name, 1 tb from table1
union
select id, name, 2 tb from table2
) a
group by id, name
order by name
结果:
| id | name_1 | name_2 |
| --- | ------ | ------ |
| 1 | chris | chris |
| 1 | john | john |
| 1 | max | max |
| 1 | null | steph |
| 1 | tony | null |
假数据:
CREATE TABLE table1 (
id int(11),
name varchar(50)
);
CREATE TABLE table2 (
id int(11),
name varchar(50)
);
INSERT INTO table1 VALUES
(1, 'max'),
(1, 'john'),
(1, 'chris'),
(1, 'tony');
INSERT INTO table2 VALUES
(1, 'steph'),
(1, 'john'),
(1, 'chris'),
(1, 'max');
还有一个 dbfiddle:https://www.db-fiddle.com/f/gQ4U7hu2S2EyFEtZrapqdu/6