具有 2 个外连接的 3 个表的 Oracle 查询
Oracle Query on 3 tables with 2 outer joins
我在编写一个看起来应该很简单的查询时遇到了一些问题,但解决方案却在逃避我。
我们有三个table(为了这个问题的目的而简化):
人员 - table 个用户名:
per_id number(10) - primary key, populated by a sequence
user_name varchar2(50)
user_id varchar2(15) - unique, basically the employee ID
work_assignments - 有点像船员分配,但更一般:
wa_id number(10) - primary key, populated by a sequence
wa_name varchar2(25)
current_assignments - 哪些用户拥有哪些 work_assignments;每个用户平均大约有 25 个工作任务,但有些 "lucky" 个人有超过 150 个:
wa_id number(10)
per_id number(10)
我正在尝试编写一个查询来比较两个用户的 work_assignments,总共三列。结果应如下所示:
WA_Name User_Name1 User_Name2
Crew A Bob Joe
Crew B Joe
Crew C Bob
基本上,两个用户中的任何一个拥有的每个 work_assignment,以及拥有它的用户的姓名。
这是我能想到的最接近的(好吧,我确实想出了一个丑陋的查询,其中包含 3 个子查询来完成这项工作,但似乎应该有一个更优雅的解决方案):
select distinct * from (
select wa.name work_assignment,
per.name user_name1,
per2.name user_name2
from work_assignments wa join current_assignments ca on wa.wa_id = ca.wa_id
join current_assignments ca2 on wa.wa_id = ca2.wa_id
left outer join persons per on per.per_id = ca.per_id and per.user_id = 'X12345'
left outer join persons per2 on per2.per_id = ca2.per_id and per2.user_id = 'Y67890'
)
where user_name1 is not null or user_name2 is not null
order by 1;
这个问题是,如果两个用户都有工作分配,它会显示 3 条记录:一条给 Bob,一条给 Joe,一条给两者:
WA_Name User_Name1 User_Name2
Crew A Bob Joe
Crew A Joe
Crew A Bob
请帮忙!
谢谢,
旦
我创建了一组样本data/tables
drop table persons;
drop table work_assgn;
drop table curr_assgn;
create table persons(
per_id number(10) not null
, user_name varchar2(10) not null
, user_id varchar2(10) not null
)
;
insert into persons values( 1, 'Bob', 'X123' );
insert into persons values( 2, 'Joe', 'Y456' );
insert into persons values( 3, 'Mike', 'Z789' );
insert into persons values( 4, 'Jeff', 'J987' );
commit;
create table work_assgn(
wa_id number(10) not null
, wa_name varchar2(25)
)
;
insert into work_assgn values( 10, 'Crew A' );
insert into work_assgn values( 20, 'Crew B' );
insert into work_assgn values( 30, 'Crew C' );
insert into work_assgn values( 40, 'Crew D' );
commit;
create table curr_assgn(
wa_id number(10) not null
, per_id number(10) not null
)
;
insert into curr_assgn values( 10, 1 );
insert into curr_assgn values( 10, 2 );
insert into curr_assgn values( 20, 2 );
insert into curr_assgn values( 30, 1 );
insert into curr_assgn values( 40, 4 );
commit;
select * from persons;
select * from work_assgn;
select * from curr_assgn;
所以数据看起来像
PERSONS
PER_ID USER_NAME USER_ID
---------- ---------- ----------
1 Bob X123
2 Joe Y456
3 Mike Z789
4 Jeff J987
WORK_ASSGN
WA_ID WA_NAME
---------- -------------------------
10 Crew A
20 Crew B
30 Crew C
40 Crew D
CURRASSGN
WA_ID PER_ID
---------- ----------
10 1
10 2
20 2
30 1
40 4
一种方法可能是使用 PIVOT
with assignment as
(
select p.user_id, p.user_name, a.wa_name
from persons p
join curr_assgn c
on p.per_id =c.per_id
join work_assgn a
on a.wa_id = c.wa_id
where p.user_id in ( 'X123', 'Y456' )
)
select * from assignment
pivot
( max(user_name) for user_id in ( 'X123', 'Y456' )
)
;
我在编写一个看起来应该很简单的查询时遇到了一些问题,但解决方案却在逃避我。
我们有三个table(为了这个问题的目的而简化): 人员 - table 个用户名:
per_id number(10) - primary key, populated by a sequence
user_name varchar2(50)
user_id varchar2(15) - unique, basically the employee ID
work_assignments - 有点像船员分配,但更一般:
wa_id number(10) - primary key, populated by a sequence
wa_name varchar2(25)
current_assignments - 哪些用户拥有哪些 work_assignments;每个用户平均大约有 25 个工作任务,但有些 "lucky" 个人有超过 150 个:
wa_id number(10)
per_id number(10)
我正在尝试编写一个查询来比较两个用户的 work_assignments,总共三列。结果应如下所示:
WA_Name User_Name1 User_Name2
Crew A Bob Joe
Crew B Joe
Crew C Bob
基本上,两个用户中的任何一个拥有的每个 work_assignment,以及拥有它的用户的姓名。
这是我能想到的最接近的(好吧,我确实想出了一个丑陋的查询,其中包含 3 个子查询来完成这项工作,但似乎应该有一个更优雅的解决方案):
select distinct * from (
select wa.name work_assignment,
per.name user_name1,
per2.name user_name2
from work_assignments wa join current_assignments ca on wa.wa_id = ca.wa_id
join current_assignments ca2 on wa.wa_id = ca2.wa_id
left outer join persons per on per.per_id = ca.per_id and per.user_id = 'X12345'
left outer join persons per2 on per2.per_id = ca2.per_id and per2.user_id = 'Y67890'
)
where user_name1 is not null or user_name2 is not null
order by 1;
这个问题是,如果两个用户都有工作分配,它会显示 3 条记录:一条给 Bob,一条给 Joe,一条给两者:
WA_Name User_Name1 User_Name2
Crew A Bob Joe
Crew A Joe
Crew A Bob
请帮忙!
谢谢, 旦
我创建了一组样本data/tables
drop table persons;
drop table work_assgn;
drop table curr_assgn;
create table persons(
per_id number(10) not null
, user_name varchar2(10) not null
, user_id varchar2(10) not null
)
;
insert into persons values( 1, 'Bob', 'X123' );
insert into persons values( 2, 'Joe', 'Y456' );
insert into persons values( 3, 'Mike', 'Z789' );
insert into persons values( 4, 'Jeff', 'J987' );
commit;
create table work_assgn(
wa_id number(10) not null
, wa_name varchar2(25)
)
;
insert into work_assgn values( 10, 'Crew A' );
insert into work_assgn values( 20, 'Crew B' );
insert into work_assgn values( 30, 'Crew C' );
insert into work_assgn values( 40, 'Crew D' );
commit;
create table curr_assgn(
wa_id number(10) not null
, per_id number(10) not null
)
;
insert into curr_assgn values( 10, 1 );
insert into curr_assgn values( 10, 2 );
insert into curr_assgn values( 20, 2 );
insert into curr_assgn values( 30, 1 );
insert into curr_assgn values( 40, 4 );
commit;
select * from persons;
select * from work_assgn;
select * from curr_assgn;
所以数据看起来像
PERSONS
PER_ID USER_NAME USER_ID
---------- ---------- ----------
1 Bob X123
2 Joe Y456
3 Mike Z789
4 Jeff J987
WORK_ASSGN
WA_ID WA_NAME
---------- -------------------------
10 Crew A
20 Crew B
30 Crew C
40 Crew D
CURRASSGN
WA_ID PER_ID
---------- ----------
10 1
10 2
20 2
30 1
40 4
一种方法可能是使用 PIVOT
with assignment as
(
select p.user_id, p.user_name, a.wa_name
from persons p
join curr_assgn c
on p.per_id =c.per_id
join work_assgn a
on a.wa_id = c.wa_id
where p.user_id in ( 'X123', 'Y456' )
)
select * from assignment
pivot
( max(user_name) for user_id in ( 'X123', 'Y456' )
)
;