如何在 Oracle 中将 table 中的两行合并为一行?
How to merge two rows from a table into one in Oracle?
我有一个包含以下列和值的 table。
Name Rate Kind NoOfItems TotalAmount
---- ---- ---- --------- -----------
ABC 1 O 50 50
ABC 2 A 10 20
(*) Table 将有 N 个名称,种类将为 O 或 A
我必须将上面的 table 数据输出到每个名字的一行中。
Name O_Rate A_Rate O_Items A_Items O_Amount A_Amount TotalItems TotalAmount
---- ------ ------ ------- ------- -------- -------- ---------- -----------
ABC 1 2 50 10 50 20 60 70
如何使用单个查询根据预期输出转换上述 table 数据。我尝试过使用 Case 和 Decode,但在这两种情况下我都只得到两行。
提前致谢。
我喜欢用条件聚合来做到这一点,但你也可以使用 join
:
select o.name, o.Rate as o_Rate, a.Rate as a_Rate,
o.Kind as o_Kind, a.Kind as a_Kind,
o.NoOfItems as o_NoOfItems, a.NoOfItems as a_NoOfItems,
o.TotalAmount as o_TotalAmount, a.TotalAmount as a_TotalAmount,
(o.NoOfItems + a.NoOfItems) as TotalItems,
(o.TotalAmount + a.TotalAmount) as TotalAmount
from t o join
t a
on o.name = a.name and o.rate = 'O' and a.rate = 'A';
从 Oracle 11.1 开始(我认为)您可以使用 PIVOT
运算符,如下所示。
更好:看来你所谓的"input"其实是一个中间结果,其他数据处理的输出。如果是这样,您可以将 PIVOT 操作与您已经在做的事情结合起来——没有理由将它作为一个单独的步骤,重复一些工作(因此重复一些执行时间)。如果您首先可以展示如何获得所谓的 "input",我们可以向您展示如何将它与旋转相结合。
with
test_data ( name, rate, kind, noofitems, totalamount ) as (
select 'ABC', 1, 'O', 50, 50 from dual
union all select 'ABC', 2, 'A', 10, 20 from dual
)
-- End of test data (not part of the solution).
-- SQL query begins BELOW THIS LINE.
select name, o_rate, a_rate, o_noofitems as o_items, a_noofitems as a_items,
o_totalamount as o_amount, a_totalamount as a_amount,
o_noofitems + a_noofitems as totalitems,
o_totalamount + a_totalamount as totalamount
from test_data
pivot(
max(rate) as rate, max(noofitems) as noofitems, max(totalamount) as totalamount
for kind in ('O' as o, 'A' as a)
)
;
NAME O_RATE A_RATE O_ITEMS A_ITEMS O_AMOUNT A_AMOUNT TOTALITEMS TOTALAMOUNT
---- ------ ------ ------- ------- -------- -------- ---------- -----------
ABC 1 2 50 10 50 20 60 70
我有一个包含以下列和值的 table。
Name Rate Kind NoOfItems TotalAmount
---- ---- ---- --------- -----------
ABC 1 O 50 50
ABC 2 A 10 20
(*) Table 将有 N 个名称,种类将为 O 或 A
我必须将上面的 table 数据输出到每个名字的一行中。
Name O_Rate A_Rate O_Items A_Items O_Amount A_Amount TotalItems TotalAmount
---- ------ ------ ------- ------- -------- -------- ---------- -----------
ABC 1 2 50 10 50 20 60 70
如何使用单个查询根据预期输出转换上述 table 数据。我尝试过使用 Case 和 Decode,但在这两种情况下我都只得到两行。
提前致谢。
我喜欢用条件聚合来做到这一点,但你也可以使用 join
:
select o.name, o.Rate as o_Rate, a.Rate as a_Rate,
o.Kind as o_Kind, a.Kind as a_Kind,
o.NoOfItems as o_NoOfItems, a.NoOfItems as a_NoOfItems,
o.TotalAmount as o_TotalAmount, a.TotalAmount as a_TotalAmount,
(o.NoOfItems + a.NoOfItems) as TotalItems,
(o.TotalAmount + a.TotalAmount) as TotalAmount
from t o join
t a
on o.name = a.name and o.rate = 'O' and a.rate = 'A';
从 Oracle 11.1 开始(我认为)您可以使用 PIVOT
运算符,如下所示。
更好:看来你所谓的"input"其实是一个中间结果,其他数据处理的输出。如果是这样,您可以将 PIVOT 操作与您已经在做的事情结合起来——没有理由将它作为一个单独的步骤,重复一些工作(因此重复一些执行时间)。如果您首先可以展示如何获得所谓的 "input",我们可以向您展示如何将它与旋转相结合。
with
test_data ( name, rate, kind, noofitems, totalamount ) as (
select 'ABC', 1, 'O', 50, 50 from dual
union all select 'ABC', 2, 'A', 10, 20 from dual
)
-- End of test data (not part of the solution).
-- SQL query begins BELOW THIS LINE.
select name, o_rate, a_rate, o_noofitems as o_items, a_noofitems as a_items,
o_totalamount as o_amount, a_totalamount as a_amount,
o_noofitems + a_noofitems as totalitems,
o_totalamount + a_totalamount as totalamount
from test_data
pivot(
max(rate) as rate, max(noofitems) as noofitems, max(totalamount) as totalamount
for kind in ('O' as o, 'A' as a)
)
;
NAME O_RATE A_RATE O_ITEMS A_ITEMS O_AMOUNT A_AMOUNT TOTALITEMS TOTALAMOUNT
---- ------ ------ ------- ------- -------- -------- ---------- -----------
ABC 1 2 50 10 50 20 60 70