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 select语句中的分类_Sql_Oracle_Group By_Case_Categories - Fatal编程技术网

Sql select语句中的分类

Sql select语句中的分类,sql,oracle,group-by,case,categories,Sql,Oracle,Group By,Case,Categories,我有这张桌子 id | object | type -------------------------------- 1 | blue | color 1 | burger | food 2 | sandwich | food 2 | red | color 2 | coke | beverage 3 |

我有这张桌子

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、颜色、食品和饮料列的表。由ID安排,上面有他们指定的东西

所以我的预期结果是

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分组,所以它为每个对象创建多行


蒂亚

您正在寻找pivot查询。问题的挑战在于,对于给定的
id
type
,可能存在多个
对象。要处理此问题,您可以首先使用
listag
对给定类型的CSV聚合对象执行
groupby
查询:

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
聚合对象,外部查询是一个简单的pivot查询,正如您所期望的那样

下面是一个小提琴图,它显示了MySQL中几乎相同的查询(Oracle似乎永远被破坏):

试试这个

我已经实现了使用子句


您可以尝试以下方法:

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
与多个类型对象的情况;您可以通过编辑
按对象排序
来修改排序。 外部查询可以以不同的方式重新编写,例如使用
透视
;我使用了
MAX
,希望把它弄清楚。

罗宾:我对你的评论(根据蒂姆·比格莱森的回答)部分是错误的。有一个基于枢轴的解决方案;然而,“组”不是按id划分的,而是按id划分的,在你的三个“类别”中排名。要使此解决方案(或任何不使用动态SQL的解决方案)正常工作,必须事先知道所有“类型”(及其名称),并且必须在SQL查询中对它们进行硬编码

注意:在这个解决方案中,我假设对于每个id,相同“类型”中的“对象”根据字母顺序相互关联(因此,例如,对于id=3,“coke”与“red”关联,“sprite”与NULL关联,与示例输出不同)。我在您的问题下方向您询问了这一点-如果您没有与我们共享其他规则,需要不同类型的对象的不同配对,则可能会也可能不会调整解决方案以满足这些其他规则

编辑:仔细看,这几乎就是Aleksej提供的,没有使用显式的
pivot
语法。他的解决方案的优点是,它可以在较旧版本的Oracle中工作(在11.1之前,
pivot
首次可用)

查询(包括第一个CTE中的测试数据):

输出:

  ID COLOR    FOOD     BEVERAGE
---- -------- -------- --------
   1 blue     burger
   2 red      sandwich coke
   3 red               coke
   3                   sprite
   4          bacon

它不会显示所有的对象。每个id只有一行正在启动。你能告诉我pivot查询如何处理我的问题吗@tim@robing-
pivot
不是您问题的解决方案。在
pivot
操作中,每个id只能得到一行
pivot
是一种聚合操作,类似于
sum
count
——每个组只能得到一个结果。再说一遍:你要做的不是一个
pivot
操作。@mathguy总是很高兴看到你对我的答案发表评论。如果OP可以接受CSV对象,那么pivot没有问题。正如你自己所说,建议的输出不是相关的,所以这个答案是解决这个问题的一种方法。@TimBiegeleisen-我实际上是在回答OP;你的答案上写的是个意外。其他人也建议采用
pivot
;OP选择在你的回答中抓住这一点,但它可能在其他地方。我对OP的观点是:要么你想要一个id可能不止一行,要么你想要一个
pivot
解决方案;不能两者都有。根据什么规则,“精灵”与“红色”关联,“可乐”与id=3的NULL关联?为什么不换个方向呢?它是随机的吗(因此其他人解决同一个问题可能会得到不同的解决方案,两种解决方案同样有效)?还是有其他规定?
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