一行中的列值

Posted

技术标签:

【中文标题】一行中的列值【英文标题】:column values in a row 【发布时间】:2012-02-28 13:12:37 【问题描述】:

我有下表

    id    count   hour   age   range
    -------------------------------------
    0       5       10     61     10-200
    1       6       20     61     10-200
    2       7       15     61     10-200  
    5       9       5      61     201-300
    7       10      25     61     201-300
    0       5       10     62     10-20
    1       6       20     62     10-20
    2       7       15     62     10-20  
    5       9       5      62     21-30
    1       8       6      62     21-30
    7       10      25     62     21-30
    10      15      30     62     31-40

我需要选择列范围的不同值 我尝试了以下查询

Select distinct range as interval from table name where age  = 62;

它的结果在一列中如下:

interval
----------
10-20
21-30
31-41

我怎样才能得到如下结果?

10-20, 21-30, 31-40

编辑: 我现在正在尝试以下查询:

select sys_connect_by_path(range,',') interval
from
    (select distinct NVL(range,'0') range , ROW_NUMBER() OVER (ORDER BY RANGE) rn 

 from table_name where age = 62)

 where connect_by_isleaf = 1 CONNECT BY rn = PRIOR rn+1 start with rn = 1;

这给了我输出:

Interval
----------------------------------------------------------------------------
, 10-20,10-20,10-20,21-30,21-30, 31-40

请大家帮我获得我想要的输出。

【问题讨论】:

【参考方案1】:

如果您使用的是 11.2 而不仅仅是 11.1,则可以使用 LISTAGG 聚合函数

SELECT listagg( interval, ',' ) 
         WITHIN GROUP( ORDER BY interval )
  FROM (SELECT DISTINCT range AS interval
          FROM table_name
         WHERE age = 62)

如果您使用的是早期版本的 Oracle,您可以使用 Tim Hall 页面上的其他 Oracle string aggregation techniques 之一。在 11.2 之前,我个人的偏好是创建一个 user-defined aggregate function 以便您可以随后

SELECT string_agg( interval )
  FROM (SELECT DISTINCT range AS interval
              FROM table_name
             WHERE age = 62)

但是,如果您不想创建函数,则可以使用 ROW_NUMBER and SYS_CONNECT_BY_PATH approach,尽管这往往会有点难以理解

with x as (
  SELECT DISTINCT range AS interval
          FROM table_name
         WHERE age = 62 )
select ltrim( max( sys_connect_by_path(interval, ','))
                keep (dense_rank last order by curr),
              ',') range
  from (select interval,
               row_number() over (order by interval) as curr,
               row_number() over (order by interval) -1 as prev
          from x)
connect by prev = PRIOR curr
  start with curr = 1

【讨论】:

没有我使用 11.1 它不支持 listagg 和连接函数。 @Pramod - 使用 11.2 之前的功能更新了我的答案

以上是关于一行中的列值的主要内容,如果未能解决你的问题,请参考以下文章

一行中的列值

如何从熊猫中的前一行复制缺失的列值[重复]

pyspark MlLib:排除一行中的列值

如何在 SQL 中显示某一行的列值?

dplyr 滞后与列值中的 n

使用正则表达式删除Mysql中列值中的括号()