使用未选择的值返回选择的合并行数

时间:2012-04-04 23:36:01

标签: sql oracle group-by

我有一个表格,格式如下:

DB_KEY     DB_VALUE
------     --------
row1       value1
row2;1     value2
row2;2     value3
row3       value4
row4;1     value5
row4;2     value6
row4;3     value7

我想只返回DB_VALUE列,如果DB_KEY的第一部分(在分号之前)在任何行上相同,则将这些行合并在一起。所以上面这个例子的回报是:

value1
value2value3
value4
value5value6value7

我想用group by做一些事情,但是如果没有选择要分组的列,似乎无法使用。即:

SELECT DB_VALUE FROM TABLE GROUP BY REXEP_SUBSTR(DB_KEY, ';', 1, 1)

任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:1)

你可以做这样的事情

SQL> ed
Wrote file afiedt.buf

  1  with x as (
  2    select 'row1' db_key, 'value1' db_value from dual union all
  3    select 'row2;1', 'value2' from dual union all
  4    select 'row2;2', 'value3' from dual union all
  5    select 'row3', 'value4' from dual union all
  6    select 'row4;1', 'value5' from dual union all
  7    select 'row4;2', 'value6' from dual union all
  8    select 'row4;3', 'value7' from dual
  9  )
 10  select key,
 11         max( sys_connect_by_path(db_value, ' '))
 12             keep( dense_rank last order by curr ) db_value
 13    from (select key,
 14                 db_value,
 15                 row_number() over (partition by key
 16                                        order by db_value) curr,
 17                 row_number() over (partition by key
 18                                        order by db_value) - 1 prev
 19            from (select substr( db_key,
 20                                 1,
 21                                 (case when instr( db_key, ';' ) = 0
 22                                       then length(db_key)
 23                                       else instr( db_key, ';' ) - 1
 24                                   end)) key,
 25                          db_value
 26                     from x))
 27     group by key
 28   connect by prev = PRIOR curr and key = prior key
 29*    start with curr = 1
SQL> /

KEY                      DB_VALUE
------------------------ ------------------------------
row1                      value1
row2                      value2 value3
row3                      value4
row4                      value5 value6 value7

您还可以查看Tim Hall列出各种string aggregation techniques in Oracle的页面。如果您使用的是Oracle 11.2,或者您可以创建函数或类型,那么您应该能够生成一个更简单的查询来生成相同的输出。

答案 1 :(得分:0)

如果您愿意创建Oracle“group_concat”聚合函数,则可以在查询中使用它来获得所需的结果。如果您搜索AskTom和group concat,您将找到所有定义。以下是一个示例:http://kb.yarmakconsulting.com/2008/06/oracle-analog-of-mysql-groupconcat.html

我想你也可以通过分层查询来做到这一点。

答案 2 :(得分:0)

您可以使用WM_CONCAT实现此目的,但不是每个人都赞同此功能 您可以使用其他一些连接函数而不是WM_CONCAT,它可以在较新版本的oracle中使用。


SELECT DISTINCT (SELECT DISTINCT NVL(WM_CONCAT(DB1.DB_VALUE), DB.DB_VALUE)
                   FROM DB_BUFFER DB1
                  WHERE SUBSTR(DB1.DB_KEY, 0, INSTR(DB1.DB_KEY, ';') - 1) =
                        SUBSTR(DB.DB_KEY, 0, INSTR(DB.DB_KEY, ';') - 1)) AS DB_VALUE
  FROM DB_BUFFER DB

这将检查DB_KEY部分的开始(之前;)。如果它匹配,它将把所有值连接到一个字符串。