多个自连接加一个内连接

时间:2013-11-04 18:20:22

标签: sql oracle self-join

我有两个表:ck_startupck_price。价格表包含列cu_typeprd_typepart_cdqtydllrs。启动表通过ck_startup.prd_type_cd = ck_price.prd_type上的一对多关系链接到价格表。

价格表包含同一产品/部件/数量但在不同客户类型下的多个条目。并非所有客户类型都具有这三个值的唯一组合。我正在尝试创建一个可以做两件事的查询:

  1. ck_startup中的某些列加入ck_price(说明和其他一些值)。
  2. 使用ck_price列为每个客户类型加入dllrs。因此,总的来说,我只有product / part / qty的每个唯一键的一个实例,以及每个客户的价格列中的值(如果有的话)。
  3. 我从未使用自助加入表格,到目前为止,我只能获取记录,以显示两个客户都有相同的选项。

    因为有人要求我发布示例代码,所以这是一个没有显示缺失价格的糟糕查询:

    select pa.*, pac.dllrs from ck_price pa
    join ck_price pac on pa.prd_type = pac.prd_type and pa.part_carbon_cd = pac.part_carbon_cd and pa.qty = pac.qty
    where pa.cu_type = 'A' and pac.cu_type = 'AC';
    

    编辑:以下是两张表中的示例数据,以及我在完成后希望它们的外观:

    CK_STARTUP
    +-----+-----------------+-------------+
    | CD  |       DSC       | PRD_TYPE_CD |
    +-----+-----------------+-------------+
    | 3D  | Stuff           | SKD3        |
    | DC  | Different stuff | SKD         |
    | DN2 | Similar stuff   | SKD         |
    +-----+-----------------+-------------+
    
    CK_PRICE
    +---------+-------------+---------+-----+-------+
    | CU_TYPE | PRD_TYPE_CD | PART_CD | QTY | DLLRS |
    +---------+-------------+---------+-----+-------+
    | A       | SKD3        |       1 | 100 |    10 |
    | A       | SKD3        |       1 | 200 |    20 |
    | A       | SKD3        |       1 | 300 |    30 |
    | A       | SKD         |       1 | 100 |    50 |
    | A       | SKD         |       1 | 200 |   100 |
    | AC      | SKD3        |       1 | 300 |    30 |
    | AC      | SKD         |       1 | 100 |   100 |
    | AC      | SKD         |       1 | 200 |   200 |
    | AC      | SKD         |       1 | 300 |   300 |
    | AC      | SKD         |       1 | 400 |   400 |
    +---------+-------------+---------+-----+-------+
    
    COMBO:
    +----+-----------------+---------+-----+---------+----------+
    | CD |       DSC       | PART_CD | QTY | DLLRS_A | DLLRS_AC |
    +----+-----------------+---------+-----+---------+----------+
    | 3D | Stuff           |       1 | 100 | 10      | null     |
    | 3D | Stuff           |       1 | 200 | 20      | null     |
    | 3D | Stuff           |       1 | 300 | 30      | 60       |
    | DC | Different stuff |       1 | 100 | 50      | 100      |
    | DC | Different stuff |       1 | 200 | 100     | 200      |
    | DC | Different stuff |       1 | 300 | null    | 300      |
    | DC | Different stuff |       1 | 400 | null    | 400      |
    +----+-----------------+---------+-----+---------+----------+
    

1 个答案:

答案 0 :(得分:1)

好的,请看下面的查询和结果:

SELECT *
FROM   (SELECT
          cs.cd, cs.dsc, cp.part_cd, cp.qty, cp.dllrs, cp.cu_type
        FROM ck_startup cs
          JOIN ck_price cp ON (cs.prd_type_cd = cp.prd_type_cd))
PIVOT (SUM(dllrs) AS dlllrs FOR (cu_type) IN ('A' AS a, 'AC' AS ac))
ORDER BY cd, qty
;

输出:

CD       DSC                  PART_CD     QTY   A_DLLLRS  AC_DLLLRS
-------- ----------------- ---------- ------- ---------- ----------
3D       Stuff                      1     100         10            
3D       Stuff                      1     200         20            
3D       Stuff                      1     300         30         30 
DC       Different stuff            1     100         50         50 
DC       Different stuff            1     200        100        100 
DC       Different stuff            1     300                   150 
DC       Different stuff            1     400                   200 
DN2      Similar stuff              1     100         50         50 
DN2      Similar stuff              1     200        100        100 
DN2      Similar stuff              1     300                   150 
DN2      Similar stuff              1     400                   200 

这不是您所期望的,因为我不明白为什么DLLRS_AC列中的CK_PRICE列中有不同的值?我的意思是,例如,为什么在输出的最后一行中有400,而不是200?为什么这个值加倍(其他人在DLLRS_AC列中)?

如果您使用的是Oracle 10g,则可以使用DECODEGROUP BY获得相同的结果,请查看:

SELECT
        cd,
        dsc,
        part_cd,
        qty,
        SUM(DECODE(cu_type, 'A', dllrs, NULL)) AS dllrs_a,
        SUM(DECODE(cu_type, 'AC', dllrs, NULL)) AS dllrs_ac
FROM (
  SELECT
    cs.cd, cs.dsc, cp.part_cd, cp.qty, cp.dllrs, cp.cu_type
  FROM ck_startup cs
    JOIN ck_price cp ON (cs.prd_type_cd = cp.prd_type_cd)
  )
GROUP BY cd, dsc, part_cd, qty
ORDER BY cd, qty;

结果是一样的。

如果您想了解更多关于旋转的信息,我建议Tim Hall撰写文章:Pivot and Unpivot at Oracle Base