代码之家  ›  专栏  ›  技术社区  ›  Alex03

Oracle数据透视/解码

  •  0
  • Alex03  · 技术社区  · 6 年前

    样本表

    EmployeeID | AssignmentID | WageCode | CompanyName | BillRate | BillTotal    
         1     |       1      | Regular  | CompanyOne  |   10     |    400
         1     |       2      | Regular  | CompanyTwo  |   11     |    440
         1     |       1      | Overtime | CompanyOne  |   15     |    150
         1     |       1      | Mileage  | CompanyOne  |    0     |     20
         2     |       3      | Regular  | CompanyThree|   20     |    800
         2     |       3      | Regular  | CompanyThree|   20     |    800
         2     |       3      | Overtime | CompanyThree|   30     |     90
         2     |       3      | Mileage  | CompanyThree|    0     |     60
    

    我只想显示按EmployeeID、WageCode、AssignmentID、CompanyName和BillRate分组的wageCode为“Regular”的行,并将其他工资代码透视到列中。

    最终结果应如下所示:

    EmployeeID | AssignmentID  | CompanyName | RegBillRate | RegBill | OTBillRate | OTBill | MileageBill
        1      |      1        | CompanyOne  |    10       |    400  | 15         |    150 |        20
        1      |      2        | CompanyTwo  |    11       |    440  |  0         |      0 |         0
        2      |      3        | CompanyThree|    20       |    1600 |  30        |     90 |        60
    

    要做到这一点,有什么更清洁的方法?这不是一堆这样的陈述:

    with regular as 
    (select EmployeeID, AssignmentID, CompanyName, BillRate, sum(BillTotal) Total from SampleTable where wage code = 'Regular' group by EmployeeID, AssignmentID, CompanyName, BillRate
    ),
    overtime as 
    (select EmployeeID, AssignmentID, CompanyName, BillRate, sum(BillTotal) Total from SampleTable where wage code = 'Overtime' group by EmployeeID, AssignmentID, CompanyName, BillRate
    ),   
    mileage as 
    (select EmployeeID, AssignmentID, CompanyName, BillRate, sum(BillTotal) Total from SampleTable where wage code = 'Mileage' group by EmployeeID, AssignmentID, CompanyName, BillRate
    )
    select r.*, o.BillRate, o.Total, m.Total
    from regular r 
    left outer join overtime o
    on r.EmployeeID = o.EmployeeID and r.AssignmentID= o.AssignmentID and r.CompanyName= o.CompanyName and r.BillRate= o.BillRateand 
    left outer join mileage m
    on r.EmployeeID = m.EmployeeID and r.AssignmentID= m.AssignmentID and r.CompanyName= m.CompanyName and r.BillRate= m.BillRateand 
    

    上面的查询是解释的,可能不起作用。

    有什么更好的方法可以通过解码和透视的组合来实现这一点?是否可以使用单个透视表?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Niharika Bitra    6 年前

    枢轴: Oracle Pivot子句允许您从Oracle11g开始编写一个交叉表查询。这意味着您可以聚合结果并将行旋转为列。

    译码: Oracle/PLSQL解码函数具有if-then-else语句的功能。

    对于您的用例,可以使用pivot并按以下方式解码:

    SELECT 
        EmployeeID, AssignmentID, CompanyName, 
        decode(REG_BILLRATE, NULL, 0, REG_BILLRATE) AS REG_BILLRATE,
        decode(REG_FILL, NULL, 0, REG_FILL) AS REG_FILL,
        decode(OT_BILLRATE, NULL, 0, OT_BILLRATE) AS OT_BILLRATE,
        decode(OT_FILL, NULL, 0, OT_FILL) AS OT_FILL,
        decode(MILEAGE_FILL, NULL, 0, MILEAGE_FILL) AS MILEAGE_FILL 
    FROM nbitra.tmp
    pivot
    (
        max(BillRate) AS BillRate, sum(BillTotal) AS Fill
        for WageCode IN ('Regular' Reg , 'Overtime' OT , 'Mileage' Mileage )
    );
    

    注意:代码将空值替换为0。

        2
  •  1
  •   Gordon Linoff    6 年前

    我认为您只需要条件聚合:

    select EmployeeID, AssignmentID, CompanyName,
           sum(case when WageCode = 'Regular' then billrate end) as regular_billrate,
           sum(case when WageCode = 'Regular' then BillTotal end) as regular_billtotal,
           sum(case when WageCode = 'Overtime' then billrate end) as ot_billrate,
           sum(case when WageCode = 'Overtime' then BillTotal end) as ot_billtotal,
           sum(case when WageCode = 'Mileage' then billrate end) as mileage_billrate,
           sum(case when WageCode = 'Mileage' then BillTotal end) as mileage_billtotal
    from SampleTable st
    group by EmployeeID, AssignmentID, CompanyName;