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子句)来创建自己的测试用例。你已经有了这些数据。对您有用的代码