Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Oracle数据透视/解码_Sql_Oracle_Pivot Table - Fatal编程技术网

Sql Oracle数据透视/解码

Sql Oracle数据透视/解码,sql,oracle,pivot-table,Sql,Oracle,Pivot Table,样本表 EmployeeID | AssignmentID | WageCode | CompanyName | BillRate | BillTotal 1 | 1 | Regular | CompanyOne | 10 | 400 1 | 2 | Regular | CompanyTwo | 11 | 440 1 | 1

样本表

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为“常规”的行,按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 
有什么更干净的方法可以做到这一点,而不是一堆这样的陈述:

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 
上面的查询是经过解释的,可能不起作用


通过解码和透视的结合,有什么更好的方法可以做到这一点?是否可以使用单个透视表?

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

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;

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

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;

PIVOT:Oracle PIVOT子句允许您从Oracle 11g开始编写交叉表格查询。这意味着您可以聚合结果并将行旋转为列

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

对于您的用例,您可以通过以下方式使用pivot和decode:

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 )
);

注意:代码将null替换为0。

PIVOT:Oracle PIVOT子句允许您从Oracle 11g开始编写交叉表格查询。这意味着您可以聚合结果并将行旋转为列

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

对于您的用例,您可以通过以下方式使用pivot和decode:

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。

这很接近,但最后的行太多,而大多数求和列都为空。@Alex03。是的,您会注意到我从
选择中删除了
WageCode
,但没有从
分组中删除。哎呀,我错了!我知道你的意思,但由于某种原因,我还是无法让它发挥作用。但这是一个有效的解决方案。总结账单价格让我有点害怕,但在我的情况下,这并不重要,因为每个组的账单价格都是唯一的。谢谢。@Alex03。您可以改用
max()
。我不确定您真正想要的是哪种逻辑。这很接近,但您最终得到的行太多,而大多数求和列都为空。@Alex03。是的,您会注意到我从
选择中删除了
WageCode
,但没有从
分组中删除。哎呀,我错了!我知道你的意思,但由于某种原因,我还是无法让它发挥作用。但这是一个有效的解决方案。总结账单价格让我有点害怕,但在我的情况下,这并不重要,因为每个组的账单价格都是唯一的。谢谢。@Alex03。您可以改用
max()
。我不知道你真正想要的是什么逻辑。这是我见过的最令人惊奇的事情。你真棒!很高兴你喜欢这个解决方案!:)神奇的这是我见过的最令人惊奇的事情。你真棒!很高兴你喜欢这个解决方案!:)