消除 JOIN 列中的重复记录
Eliminate duplicates of records in the column on JOIN
初始数据示例:
Table 1 Table 2
| ID | Name | Cost | Cost2 | | ID | Info1 | Info2 |
|-------|----------|---------|---------| |-------|-----------|-----------|
| 1 | Name1 | 20 | 50 | | 1 | text1 | text1 |
| 2 | Name2 | 30 | 10 | | 1 | text1 | text1 |
| 2 | Name22 | 30 | 40 | | 1 | text1 | text1 |
| 3 | Name3 | 20 | 50 | | 2 | text21 | text21 |
| 4 | Name4 | 30 | 70 | | 2 | text22 | text22 |
| 2 | text23 | text23 |
| 2 | text24 | text24 |
在我的初始数据中,我通过字段 ID 在 2 table 之间建立了关系。我需要将第二个 table 加入第一个。
所以这是 Leftjoin
通过 table1.ID
= table2.ID
的简单结果
| ID | Name | Cost | Cost2 | Info1 | Info2 |
|-------|----------|---------|---------|-----------|-----------|
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 2 | Name2 | 30 | 10 | text21 | text21 |
| 2 | Name2 | 30 | 10 | text22 | text22 |
| 2 | Name2 | 30 | 10 | text23 | text23 |
| 2 | Name2 | 30 | 10 | text24 | text24 |
| 2 | Name22 | 60 | 40 | text21 | text21 |
| 2 | Name22 | 60 | 40 | text22 | text22 |
| 2 | Name22 | 60 | 40 | text23 | text23 |
| 2 | Name22 | 60 | 40 | text24 | text24 |
如何通过 join
在字段 (Cost, Cost2)
上获得结果而无需重复
预期结果:
| ID | Name | Cost | Cost2 | Info1 | Info2 |
|-------|----------|---------|---------|-----------|-----------|
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 1 | Name1 | NULL | NULL | text1 | text1 |
| 1 | Name1 | NULL | NULL | text1 | text1 |
| 2 | Name2 | 30 | 10 | text21 | text21 |
| 2 | Name2 | NULL | NULL | text22 | text22 |
| 2 | Name2 | NULL | NULL | text23 | text23 |
| 2 | Name2 | NULL | NULL | text24 | text24 |
| 2 | Name22 | 30 | 40 | text21 | text21 |
| 2 | Name22 | NULL | NULL | text22 | text22 |
| 2 | Name22 | NULL | NULL | text23 | text23 |
| 2 | Name22 | NULL | NULL | text24 | text24 |
您需要一个 "line number" 作为 join
。您的表没有,但您可以使用 row_number()
:
添加一个
select coalesce(t1.id, t2.id) as id,
t1.name, t1.cost, t2.info1, t2.info2
. . .
from (select t1.*, row_number() over (partition by id order by (select null)) as seqnum
from table1 t1
) full join
(select t2.*, row_number() over (partition by id order by (select null)) as seqnum
from table2 t2
) t2
on t1.id = t2.id and t1.seqnum = t2.seqnum;
唉,您不能使用此方法获得 name
。但这是有道理的。它仅在 table1
中,因此不应出现在每个匹配行中。
编辑:
这不完全正确。您希望重复这些行。然后值不出现。我认为这是条件逻辑:
如果你确实需要它:
select t1.id, t1.name,
(case when row_number() over (partition by t1.id order by (select null)) = 1 then cost END) as Cost,
t2.info1, t2.info2
from table1 t1 join
table2 t2
on t1.id = t2.id ;
你可以尝试使用row_number
window函数在子查询中生成行号然后通过CASE WHEN
得到Cost
和Cost2
,其中的行号是1
SELECT ID,
Name,
CASE WHEN rn = 1 THEN Cost end,
CASE WHEN rn = 1 THEN Cost2 end,
Info1,
Info2
FROM (
SELECT
t1.ID,
Name,
Cost,
Cost2,
Info1,
Info2,
row_number() over(partition by Name order by Info1) rn
FROM Table1 t1 JOIN table2 t2 on t1.id = t2.id
) t1
初始数据示例:
Table 1 Table 2
| ID | Name | Cost | Cost2 | | ID | Info1 | Info2 |
|-------|----------|---------|---------| |-------|-----------|-----------|
| 1 | Name1 | 20 | 50 | | 1 | text1 | text1 |
| 2 | Name2 | 30 | 10 | | 1 | text1 | text1 |
| 2 | Name22 | 30 | 40 | | 1 | text1 | text1 |
| 3 | Name3 | 20 | 50 | | 2 | text21 | text21 |
| 4 | Name4 | 30 | 70 | | 2 | text22 | text22 |
| 2 | text23 | text23 |
| 2 | text24 | text24 |
在我的初始数据中,我通过字段 ID 在 2 table 之间建立了关系。我需要将第二个 table 加入第一个。
所以这是 Leftjoin
通过 table1.ID
= table2.ID
| ID | Name | Cost | Cost2 | Info1 | Info2 |
|-------|----------|---------|---------|-----------|-----------|
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 2 | Name2 | 30 | 10 | text21 | text21 |
| 2 | Name2 | 30 | 10 | text22 | text22 |
| 2 | Name2 | 30 | 10 | text23 | text23 |
| 2 | Name2 | 30 | 10 | text24 | text24 |
| 2 | Name22 | 60 | 40 | text21 | text21 |
| 2 | Name22 | 60 | 40 | text22 | text22 |
| 2 | Name22 | 60 | 40 | text23 | text23 |
| 2 | Name22 | 60 | 40 | text24 | text24 |
如何通过 join
在字段 (Cost, Cost2)
预期结果:
| ID | Name | Cost | Cost2 | Info1 | Info2 |
|-------|----------|---------|---------|-----------|-----------|
| 1 | Name1 | 20 | 50 | text1 | text1 |
| 1 | Name1 | NULL | NULL | text1 | text1 |
| 1 | Name1 | NULL | NULL | text1 | text1 |
| 2 | Name2 | 30 | 10 | text21 | text21 |
| 2 | Name2 | NULL | NULL | text22 | text22 |
| 2 | Name2 | NULL | NULL | text23 | text23 |
| 2 | Name2 | NULL | NULL | text24 | text24 |
| 2 | Name22 | 30 | 40 | text21 | text21 |
| 2 | Name22 | NULL | NULL | text22 | text22 |
| 2 | Name22 | NULL | NULL | text23 | text23 |
| 2 | Name22 | NULL | NULL | text24 | text24 |
您需要一个 "line number" 作为 join
。您的表没有,但您可以使用 row_number()
:
select coalesce(t1.id, t2.id) as id,
t1.name, t1.cost, t2.info1, t2.info2
. . .
from (select t1.*, row_number() over (partition by id order by (select null)) as seqnum
from table1 t1
) full join
(select t2.*, row_number() over (partition by id order by (select null)) as seqnum
from table2 t2
) t2
on t1.id = t2.id and t1.seqnum = t2.seqnum;
唉,您不能使用此方法获得 name
。但这是有道理的。它仅在 table1
中,因此不应出现在每个匹配行中。
编辑:
这不完全正确。您希望重复这些行。然后值不出现。我认为这是条件逻辑:
如果你确实需要它:
select t1.id, t1.name,
(case when row_number() over (partition by t1.id order by (select null)) = 1 then cost END) as Cost,
t2.info1, t2.info2
from table1 t1 join
table2 t2
on t1.id = t2.id ;
你可以尝试使用row_number
window函数在子查询中生成行号然后通过CASE WHEN
得到Cost
和Cost2
,其中的行号是1
SELECT ID,
Name,
CASE WHEN rn = 1 THEN Cost end,
CASE WHEN rn = 1 THEN Cost2 end,
Info1,
Info2
FROM (
SELECT
t1.ID,
Name,
Cost,
Cost2,
Info1,
Info2,
row_number() over(partition by Name order by Info1) rn
FROM Table1 t1 JOIN table2 t2 on t1.id = t2.id
) t1