所以我有这张桌子
id | object | type
--------------------------------
1 | blue | color
1 | burger | food
2 | sandwich | food
2 | red | color
2 | coke | beverage
3 | sprite | beverage
3 | coke | beverage
3 | red | color
4 | bacon | food
我必须创建一个select语句,它将显示一个包含id,color,food和beverage列的表。由身份证安排,并附上指定的东西。
所以我的预期结果是
id | color | food | beverage
-------------------------------------------
1 | blue | burger |
2 | red | sandwich | coke
3 | red | | sprite
3 | | | coke
4 | | bacon |
截至目前我有这段代码
Select id as id,
Case When I.Type = 'color' Then I.Object End As color,
Case When I.Type = 'food' Then I.Object End As food,
Case When I.Type = 'beverage' Then I.Object End As beverage
From table I
order by id
但我的代码问题是它没有按ID分组,所以它为每个对象创建了多行。
TIA!
答案 0 :(得分:1)
您正在寻找透视查询。对您的问题有挑战性的是,对于给定的id
和 type
,可能会有多个object
存在。要处理此问题,您可以先使用GROUP BY
对给定类型的CSV聚合对象进行LISTAGG
查询:
SELECT id,
MAX(CASE WHEN t.type = 'color' THEN t.object ELSE NULL END) AS color,
MAX(CASE WHEN t.type = 'food' THEN t.object ELSE NULL END) AS food,
MAX(CASE WHEN t.type = 'beverage' THEN t.object ELSE NULL END) AS beverage
FROM
(
SELECT id,
LISTAGG(object, ',') WITHIN GROUP (ORDER BY object) AS object,
type
FROM yourTable
GROUP BY id, type
) t
GROUP BY t.id
内部查询首先聚合id
和 type
中的对象,外部查询是您可能期望的简单数据透视查询。
这是一个小提琴,在MySQL中显示几乎相同的查询(Oracle似乎永远被打破):
答案 1 :(得分:1)
您可以尝试使用以下内容:
with test(id, object, type) as
(
select 1,'blue', 'color' from dual union all
select 1,'burger', 'food' from dual union all
select 2,'sandwich','food' from dual union all
select 2,'red', 'color' from dual union all
select 2,'coke', 'beverage' from dual union all
select 3,'sprite', 'beverage' from dual union all
select 3,'coke', 'beverage' from dual union all
select 3,'red', 'color' from dual union all
select 4,'bacon', 'food' from dual
)
select id,
max( case when type = 'color'
then object
else null
end
) as color,
max( case when type = 'food'
then object
else null
end
) as food,
max( case when type = 'beverage'
then object
else null
end
) as beverage
from (
select id, object, type, row_number() over ( partition by id, type order by object) row_for_id
from test
)
group by id, row_for_id
order by id, row_for_id
内部查询是主要部分,您可以在其中处理具有许多类型对象的单个id
的情况;您可以通过编辑order by object
来修改排序。
外部查询可以以不同的方式重写,例如使用PIVOT
;我使用MAX
希望明确表达。
答案 2 :(得分:0)
试试这个
我已经使用pivot子句
select id,object,type from yourtable
pivot
(
LISTAGG(object, ',') WITHIN GROUP (ORDER BY object)
for type IN
(
'color' AS "color",
'food' AS "food",
'beverage' AS "beverage"
)
)
order by id
答案 3 :(得分:0)
注意:在此解决方案中,我假设对于每个id,同一“类型”中的“对象”基于其字母顺序彼此关联(例如,对于id = 3,“coke”与“red”关联,“sprite”与NULL关联,与示例输出不同)。我在你的问题下面问过你 - 如果你没有与我们分享其他规则,要求不同类型的对象配对,则可能会或可能不会调整解决方案以满足这些附加规则。 / p>
编辑:仔细看看,这几乎是Aleksej提供的内容,而不使用显式的pivot
语法。他的解决方案的优势在于它可以在旧版本的Oracle中使用(在11.1之前pivot
首次可用)。
QUERY(包括第一次CTE中的测试数据):
with
inputs ( id, object, type ) as (
select 1, 'blue' , 'color' from dual union all
select 1, 'burger' , 'food' from dual union all
select 2, 'sandwich' , 'food' from dual union all
select 2, 'red' , 'color' from dual union all
select 2, 'coke' , 'beverage' from dual union all
select 3, 'sprite' , 'beverage' from dual union all
select 3, 'coke' , 'beverage' from dual union all
select 3, 'red' , 'color' from dual union all
select 4, 'bacon' , 'food' from dual
),
r ( id, object, type, rn ) as (
select id, object, type, row_number() over (partition by id, type order by object)
from inputs
)
select id, color, food, beverage
from r
pivot ( max(object) for type in ( 'color' as color, 'food' as food,
'beverage' as beverage))
order by id, rn
;
输出:
ID COLOR FOOD BEVERAGE
---- -------- -------- --------
1 blue burger
2 red sandwich coke
3 red coke
3 sprite
4 bacon