使用 Oracle SQL 在多个列上旋转多个组的最有效方法?
Posted
技术标签:
【中文标题】使用 Oracle SQL 在多个列上旋转多个组的最有效方法?【英文标题】:Most efficient way to pivot multiple groups over multiple columns using Oracle SQL? 【发布时间】:2020-08-28 21:11:20 【问题描述】:任何人都可以帮助确定使用 Oracle SQL 在多个组中、跨多个列中透视数据的最有效方法吗?
我有一张如下表:
NAME MEAL FOOD DRINK
Dan Lunch Taco Coke
Dan Dinner Steak Water
Becky Lunch Pizza Coke
Becky Dinner Pizza Milk
而我想要的输出如下表:
NAME LUNCH_FOOD LUNCH_DRINK DINNER_FOOD DINNER_DRINK
Dan Taco Coke Steak Water
Becky Pizza Coke Pizza Milk
执行此操作的最佳方法是什么?我下面的解决方案完成了任务,但我觉得有一种更有效的方法:
数据:
CREATE TABLE EXAMPLE (PERSON VARCHAR(10), MEAL VARCHAR(10), FOOD VARCHAR(10), DRINK VARCHAR(10));
INSERT INTO EXAMPLE (PERSON, MEAL, FOOD, DRINK) VALUES ('Dan', 'Lunch', 'Taco', 'Coke');
INSERT INTO EXAMPLE (PERSON, MEAL, FOOD, DRINK) VALUES ('Dan', 'Dinner', 'Steak', 'Water');
INSERT INTO EXAMPLE (PERSON, MEAL, FOOD, DRINK) VALUES ('Becky', 'Lunch', 'Pizza', 'Coke');
INSERT INTO EXAMPLE (PERSON, MEAL, FOOD, DRINK) VALUES ('Becky', 'Dinner', 'Pizza', 'Milk');
当前解决方案:
SELECT t1."PERSON",
t1."FOOD" AS "LUNCH_FOOD",
t1."DRINK" AS "LUNCH_DRINK",
t2."FOOD" AS "DINNER_FOOD",
t2."DRINK" AS "DINNER_DRINK"
FROM (SELECT *
FROM EXAMPLE
WHERE "MEAL" = 'Lunch') t1
FULL JOIN (SELECT *
FROM EXAMPLE
WHERE "MEAL" = 'Dinner') t2
ON t1."PERSON" = t2."PERSON";
编辑:应该注意我在这里使用的是完全加入,因为在实际用例中存在一个人可能在一个组中但不是另一个人的实例(即,某人可能有午餐条目但没有相应的晚餐入口)。此外,可以假设每个人只有 1 顿午餐和 1 顿晚餐,永远不会更多。
【问题讨论】:
【参考方案1】:我建议聚合:
select name,
max(case when meal = 'Lunch' then food end) as lunch_food,
max(case when meal = 'Lunch' then drink end) as lunch_drink,
max(case when meal = 'Dinner' then food end) as dinner_food,
max(case when meal = 'Dinner' then drink end) as dinner_drink
from example
group by name;
但是,如果您有一张大桌子,您可以将其与:
select name, l.food, l.drink, d.food, d.drink
from (select e.*
from example e
where meal = 'Lunch'
) l full join
(select e.*
from dinner e
where meal = 'Dinner'
) d
using (name);
Oracle 具有高效的聚合机制。很难说哪个会更快,所以你应该试试你的数据。
【讨论】:
【参考方案2】:select *
from example
pivot (
max(FOOD) as FOOD,max(DRINK) as DRINK
for MEAL in ('Lunch' as Lunch,'Dinner' as Dinner)
);
结果:
PERSON LUNCH_FOOD LUNCH_DRINK DINNER_FOOD DINNER_DRINK
---------- ---------- ------------ ------------ ------------
Becky Pizza Coke Pizza Milk
Dan Taco Coke Steak Water
【讨论】:
以上是关于使用 Oracle SQL 在多个列上旋转多个组的最有效方法?的主要内容,如果未能解决你的问题,请参考以下文章