Oracle 如何基于状态连接表记录?
我有一个表,它必须根据状态连接到另一个表。以下是表1数据的示例:Oracle 如何基于状态连接表记录?,oracle,oracle11g,left-join,oracle-sqldeveloper,Oracle,Oracle11g,Left Join,Oracle Sqldeveloper,我有一个表,它必须根据状态连接到另一个表。以下是表1数据的示例: ROWID STATE 34 TX 56 NY 67 WA 89 TX 表1中的每一行都有状态值。表2为每个州提供了两条记录。下面是一个例子: ROWID STATE NAME 19 TX Chuck, Brown 20 TX Nick, Johnes 如表2所示,德克萨斯州有两项记录。如果我使用左外连接并尝试执行以下操作
ROWID STATE
34 TX
56 NY
67 WA
89 TX
表1中的每一行都有状态值。表2为每个州提供了两条记录。下面是一个例子:
ROWID STATE NAME
19 TX Chuck, Brown
20 TX Nick, Johnes
如表2所示,德克萨斯州有两项记录。如果我使用左外连接
并尝试执行以下操作:
LEFT OUTER JOIN Table 2 TB2
ON TB1.STATE = TB2.SATE
34 TX Chuck, Brwon
34 TX Nick, Johnes
89 TX Chuck, Brwon
89 TX Nick, Johnes
然后输出将如下所示:
LEFT OUTER JOIN Table 2 TB2
ON TB1.STATE = TB2.SATE
34 TX Chuck, Brwon
34 TX Nick, Johnes
89 TX Chuck, Brwon
89 TX Nick, Johnes
每一行都是重复的,因为表1中有两条德克萨斯州的记录。表2中有两条德克萨斯州的记录。我想看到的是:
ROWID STATE NAME 1 NAME 2
34 TX Chuck, Brwon Nick, Johnes
基本上我想把两行合并成一行,然后加入表1。我最近开始做这个项目,我们使用Oracle数据库。如果有人知道实现这一目标的好方法,请让我知道。谢谢。基于示例所需的输出,我将输出限制为表1中的第一个状态实例,并按ID对数据透视名称进行排序,尽管这恰好与给定示例数据的名称字段的alpha顺序相匹配 看到这个了吗 Oracle 11g R2架构设置:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
请注意,在Oracle中,ROWID是一个保留名称,因此我将其更改为ID
查询1:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
查询2:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
基于示例所需的输出,我将输出限制为表1中的第一个state实例,并按ID对数据透视名称进行排序,尽管这恰好与给定示例数据的name字段的alpha顺序相匹配 看到这个了吗 Oracle 11g R2架构设置:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
请注意,在Oracle中,ROWID是一个保留名称,因此我将其更改为ID
查询1:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
查询2:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
:
select t1.id
, t2.state
, t2.name
from (select min(id) id, state from table1 group by state) t1
join table2 t2
on t1.state = t2.state
| ID | STATE | NAME |
|----|-------|--------------|
| 34 | TX | Nick, Johnes |
| 34 | TX | Chuck, Brown |
with t1(id, state) as (
select min(id) id, state from table1 group by state
), t2 as (
select state
, row_number() over (partition by state order by name) rn
, name
from table2
)
select t1.id
, pvt.*
from t1
join t2 pivot (max(name) for rn in (1 name_1,2 name_2)) pvt
on t1.state = pvt.state
| ID | STATE | NAME_1 | NAME_2 |
|----|-------|--------------|--------------|
| 34 | TX | Chuck, Brown | Nick, Johnes |
正如你在问题下的一条评论中所说,你会接受一个单一的、连接的名称列,这里有一个选项;我使用CTE创建表,所以需要从第13行开始
SQL> with
2 t1 (rid, state) as
3 (select 34, 'TX' from dual union all
4 select 56, 'NY' from dual union all
5 select 67, 'WA' from dual union all
6 select 89, 'TX' from dual
7 ),
8 t2 (rid, state, name) as
9 (select 19, 'TX', 'Chuck, Brown' from dual union all
10 select 20, 'TX', 'Nick, Johnes' from dual
11 ),
12 -- start here
13 it2 as
14 (select state, listagg(name, ' & ') within group (order by null) name
15 from t2
16 group by state
17 )
18 select min(t1.rid) rid,
19 t1.state,
20 it2.name
21 from t1 join it2 on t1.state = it2.state
22 and t1.state = 'TX'
23 group by t1.state, it2.name;
RID ST NAME
---------- -- ------------------------------
34 TX Chuck, Brown & Nick, Johnes
SQL>
正如你在问题下的一条评论中所说,你会接受一个单一的、连接的名称列,这里有一个选项;我使用CTE创建表,所以需要从第13行开始
SQL> with
2 t1 (rid, state) as
3 (select 34, 'TX' from dual union all
4 select 56, 'NY' from dual union all
5 select 67, 'WA' from dual union all
6 select 89, 'TX' from dual
7 ),
8 t2 (rid, state, name) as
9 (select 19, 'TX', 'Chuck, Brown' from dual union all
10 select 20, 'TX', 'Nick, Johnes' from dual
11 ),
12 -- start here
13 it2 as
14 (select state, listagg(name, ' & ') within group (order by null) name
15 from t2
16 group by state
17 )
18 select min(t1.rid) rid,
19 t1.state,
20 it2.name
21 from t1 join it2 on t1.state = it2.state
22 and t1.state = 'TX'
23 group by t1.state, it2.name;
RID ST NAME
---------- -- ------------------------------
34 TX Chuck, Brown & Nick, Johnes
SQL>
每个
状态
是否总是有零个、一个或两个名称
记录?或者该数字在设计时是可变的和/或未知的?什么决定了哪个Name
是Name 1
还是Name 2
?@APC表2中的状态总是有两条记录。没有什么特别的东西可以决定名称1
或名称2
。总是应该有两个名字。我所需要的只是将它们组合起来(例如,像这样连接Josh、Brown和Micky,Butt)。如果表1中有两条TX记录,但在最终结果中只有一条结果记录,那该怎么办呢。如何正确选择发送记录?或者,当按ROWID排序时,是否要将第一个名称与第一个TX记录合并,将第二个名称与第二个TX记录合并?@SentinelIf如果仔细查看上面的示例,您将看到具有左外部合并的当前代码是重复行。我想将同一状态的名称合并到一行中。例如,在表2中,TX应该有一条记录,名称应该是像Chuck,Brwon&Nick,Johnes这样的,或者是两列名称1和名称2。我希望这将帮助您理解我试图实现的目标。不需要外部联接,除非您希望返回表1中的所有记录,即使表2中不存在匹配的记录。请参阅下面我的答案,它提供了所需的输出,但不使用外部联接。每个状态
是否总是有零个、一个或两个名称
记录?或者该数字在设计时是可变的和/或未知的?什么决定了哪个Name
是Name 1
还是Name 2
?@APC表2中的状态总是有两条记录。没有什么特别的东西可以决定名称1
或名称2
。总是应该有两个名字。我所需要的只是将它们组合起来(例如,像这样连接Josh、Brown和Micky,Butt)。如果表1中有两条TX记录,但在最终结果中只有一条结果记录,那该怎么办呢。如何正确选择发送记录?或者,当按ROWID排序时,是否要将第一个名称与第一个TX记录合并,将第二个名称与第二个TX记录合并?@SentinelIf如果仔细查看上面的示例,您将看到具有左外部合并的当前代码是重复行。我想将同一状态的名称合并到一行中。例如,在表2中,TX应该有一条记录,名称应该是像Chuck,Brwon&Nick,Johnes这样的,或者是两列名称1和名称2。我希望这将帮助您理解我试图实现的目标。不需要外部联接,除非您希望返回表1中的所有记录,即使表2中不存在匹配的记录。请参阅下面我的答案,它提供了所需的输出,但不使用外部联接。