Oracle Pivot /解码

时间:2019-02-12 21:34:06

标签: sql oracle pivot-table

样品表

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

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

最终结果应如下所示:

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 个答案:

答案 0 :(得分:2)

PIVOT:使用Oracle PIVOT子句,您可以从Oracle 11g开始编写交叉表查询。这意味着您可以汇总结果并将行旋转为列。

DECODE: Oracle / PLSQL DECODE函数具有IF-THEN-ELSE语句的功能。

对于您的用例,可以通过以下方式使用数据透视和解码:

import os, shutil
import os.path, time
path = 'C:/Users/saqibshakeel035/Desktop/Folder_1/'
copyto= 'C:/Users/saqibshakeel035/Desktop/Folder_2/'
files = os.listdir(path)
files.sort()

for f in files:
        print(f) #f contains the names of files
        src = path+f #path of source
        dst = copyto+f #path of destination
        shutil.copy(src,dst) #copying from source to destination
        print("This is source" +src)
        print("This is destination " +dst)
        print(f)

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

答案 1 :(得分:1)

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

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;