Sql 组合多个表时如何复制列或记录
我不知道标题是否描述了我的要求。我有一个表Sql 组合多个表时如何复制列或记录,sql,oracle,Sql,Oracle,我不知道标题是否描述了我的要求。我有一个表C\u Bpartner(主键为C\u Bpartner\u ID),供这样的员工使用: name Hiringorderno Orderdate C\u Bpartner\u ID A 30 25/02/2002 100 b4713/10/2005 101 D 110 2010年9月22日105 以及其他表格,如emp_培训: C\u Bpartner\u ID培训或无订单日期 100 46 2012年5月14日 1005810/07/2013 101
C\u Bpartner
(主键为C\u Bpartner\u ID
),供这样的员工使用:name Hiringorderno Orderdate C\u Bpartner\u ID
A 30 25/02/2002 100
b4713/10/2005 101
D 110 2010年9月22日105
以及其他表格,如emp_培训:
C\u Bpartner\u ID培训或无订单日期
100 46 2012年5月14日
1005810/07/2013
1017622/10/2015
以及emp_处罚:
C\u Bpartner\u ID PenaltyOrderno Orderdate
105 133 14/05/2012
10115325/03/2018
我希望生成的表如下所示:
name orderno Orderdate C\u Bpartner\u ID
A 30 2012年2月25日100
A 46 2005年5月14日100
A 58 2013年7月10日100
b4713/10/2005 101
B 76 22/10/2015 101
B15325/03/2018 101
D 110 2010年9月22日105
D13314/05/2012 105
因此,我加入了
C\u BPartner
,并将它们合并,以便为相同的C\u BPartner\u ID
获得第二条记录。然后尝试从C\u BPartner bp
获取Hiringorderno
,并将C\u BPartner pp
与emp\u popular pt
(作为一个示例)连接,并获取PenaltyOrderno
并将它们与coalesce(bp.Hiringorderno,pt.PenaltyOrderno)结合起来,对所有其他表和Orderdate也这样做。但它不会复制记录。它拾取第一个合并参数并丢弃另一个。像这样
coalesce(bp.name,pp.name) coalesce(bp.Hiringorderno,pt.PenaltyOrderno) Hiringorderno PenaltyOrderno
A 30 30 null
B 47 47 153
B的emp_处罚记录不存在 还有其他方法可以做到这一点,但我认为最清晰、最直观的方法是将您尝试执行的3个查询合并起来
select name, hiringorderno as orderno, orderdate, C_Bpartner_ID, 'HIRING' as ordertype, null as emp_penalty_ID
from C_Bpartner
union all
select bp.name, trainingorderno, t.orderdate, bp.C_Bpartner_ID, 'TRAINING', null
from emp_training t
join C_Bpartner bp
on bp.C_Bpartner_ID = t.C_Bpartner_ID
union all
select bp.name, PenaltyOrderno, p.orderdate, bp.C_Bpartner_ID, 'PENALTY', p.emp_penalty_ID
from emp_penalty p
join C_Bpartner bp
on bp.C_Bpartner_ID = p.C_Bpartner_ID
;
编辑:我添加了两列来显示区分联合记录的两种常用方法
一种方法是在每个select语句中添加一个常量字符串或数字-这样,当ordertype='Penal'…或其中ordertype='TRAINING'
时,您可以使用CASE来筛选记录
另一种方法,如您所提到的,是为其中一个select语句(如emp_惩罚_id)填充一列,但为其他select语句将其设置为null
联合在一起的所有select语句都需要具有相同的列数和兼容的类型。第一个select语句定义了其余部分的列名和类型,这就是为什么我不需要在第二个和第三个select语句中添加列别名的原因。还有其他方法可以做到这一点,但我认为最清晰直观的方法是合并您尝试执行的3个查询
select name, hiringorderno as orderno, orderdate, C_Bpartner_ID, 'HIRING' as ordertype, null as emp_penalty_ID
from C_Bpartner
union all
select bp.name, trainingorderno, t.orderdate, bp.C_Bpartner_ID, 'TRAINING', null
from emp_training t
join C_Bpartner bp
on bp.C_Bpartner_ID = t.C_Bpartner_ID
union all
select bp.name, PenaltyOrderno, p.orderdate, bp.C_Bpartner_ID, 'PENALTY', p.emp_penalty_ID
from emp_penalty p
join C_Bpartner bp
on bp.C_Bpartner_ID = p.C_Bpartner_ID
;
编辑:我添加了两列来显示区分联合记录的两种常用方法
一种方法是在每个select语句中添加一个常量字符串或数字-这样,当ordertype='Penal'…
或其中ordertype='TRAINING'
时,您可以使用CASE来筛选记录
另一种方法,如您所提到的,是为其中一个select语句(如emp_惩罚_id)填充一列,但为其他select语句将其设置为null
联合在一起的所有select语句都需要具有相同的列数和兼容的类型。第一个select语句定义了其余部分的列名和类型,这就是我不需要在第二个和第三个select语句中添加列别名的原因。一个选项是联合3个查询:
SQL> with
2 c_bpartner (name, hiringorderno, orderdate, c_bpartner_id) as
3 (select 'A', 30, date '2002-02-25', 100 from dual union all
4 select 'B', 47, date '2005-10-13', 101 from dual union all
5 select 'D', 110,date '2010-09-22', 105 from dual
6 ),
7 emp_training(c_bpartner_id, trainingorderno, orderdate) as
8 (select 100, 46, date '2012-05-14' from dual union all
9 select 100, 58, date '2013-07-10' from dual union all
10 select 101, 76, date '2015-10-22' from dual
11 ),
12 emp_penalty (c_bpartner_id, penaltyorderno, orderdate) as
13 (select 105, 133, date '2012-05-14' from dual union all
14 select 101, 153, date '2018-03-25' from dual
15 )
16 select c.name, c.hiringorderno as orderno, c.orderdate, c.c_bpartner_id
17 from c_bpartner c
18 union all
19 select c.name, t.trainingorderno, t.orderdate, t.c_bpartner_id
20 from c_bpartner c join emp_training t on t.c_bpartner_id = c.c_bpartner_id
21 union all
22 select c.name, p.penaltyorderno, p.orderdate, p.c_bpartner_id
23 from c_bpartner c join emp_penalty p on p.c_bpartner_id = c.c_bpartner_id
24 order by 1, 2;
N ORDERNO ORDERDATE C_BPARTNER_ID
- ---------- ---------- -------------
A 30 25/02/2002 100
A 46 14/05/2012 100
A 58 10/07/2013 100
B 47 13/10/2005 101
B 76 22/10/2015 101
B 153 25/03/2018 101
D 110 22/09/2010 105
D 133 14/05/2012 105
8 rows selected.
SQL>
一个选项是联合3个查询:
SQL> with
2 c_bpartner (name, hiringorderno, orderdate, c_bpartner_id) as
3 (select 'A', 30, date '2002-02-25', 100 from dual union all
4 select 'B', 47, date '2005-10-13', 101 from dual union all
5 select 'D', 110,date '2010-09-22', 105 from dual
6 ),
7 emp_training(c_bpartner_id, trainingorderno, orderdate) as
8 (select 100, 46, date '2012-05-14' from dual union all
9 select 100, 58, date '2013-07-10' from dual union all
10 select 101, 76, date '2015-10-22' from dual
11 ),
12 emp_penalty (c_bpartner_id, penaltyorderno, orderdate) as
13 (select 105, 133, date '2012-05-14' from dual union all
14 select 101, 153, date '2018-03-25' from dual
15 )
16 select c.name, c.hiringorderno as orderno, c.orderdate, c.c_bpartner_id
17 from c_bpartner c
18 union all
19 select c.name, t.trainingorderno, t.orderdate, t.c_bpartner_id
20 from c_bpartner c join emp_training t on t.c_bpartner_id = c.c_bpartner_id
21 union all
22 select c.name, p.penaltyorderno, p.orderdate, p.c_bpartner_id
23 from c_bpartner c join emp_penalty p on p.c_bpartner_id = c.c_bpartner_id
24 order by 1, 2;
N ORDERNO ORDERDATE C_BPARTNER_ID
- ---------- ---------- -------------
A 30 25/02/2002 100
A 46 14/05/2012 100
A 58 10/07/2013 100
B 47 13/10/2005 101
B 76 22/10/2015 101
B 153 25/03/2018 101
D 110 22/09/2010 105
D 133 14/05/2012 105
8 rows selected.
SQL>
请在您的问题中添加一个迄今为止您已经完成的代码。谢谢我的问题已经解决了,谢谢你,不管怎样,我知道,我两天前问过:)你很好,请在你的问题中添加一个代码,你到目前为止已经完成了。谢谢我知道,我两天前问过:)您好,这对我没用,因为我的表没有记录限制,它不只是三列或三列。总有一个新的记录太糟糕了。但是,它完全按照您的要求执行,并返回您想要的结果。此外,我不明白“因为等”是什么意思。我指的是这个代码部分<代码>选择“A”,30,日期“2002-02-25”,100来自双联所有4个选择“B”,47,日期“2005-10-13”,101来自双联所有5个选择“D”,110,日期“2010-09-22”,105来自双联
。我无法手动插入所有记录。这些表中有1000多条记录,没有人希望您手动输入这些记录。如果您提供了测试用例(创建表并插入到样本数据中),我就不必使用CTE(公共表表达式,又称带factoring子句)来创建自己的测试用例。你已经有了这些数据。对您有用的代码