1. 程式人生 > 其它 >Oracle列轉行函式——listagg()

Oracle列轉行函式——listagg()

前言

今天要幫業務寫一個取數的SQL,其中要用到分組函式,並且要取到各個分組內詳細的資料,因為用到的比較少,不太清楚要怎麼實現,在網上找到listagg函式可以實現,所以記錄下它的應用

Listagg()詳解

概述

listagg()函式可以實現多列記錄聚合為一條記錄,其實就是列轉行;可以單獨使用,也可以與GROUP BY一起使用
像聚合函式一樣,通過Group by語句,把每個Group的一個欄位,拼接起來

基本語法

LISTAGG(measure_expr,delimiter) WITHIN GROUP( ORDER BY XXX)

  • measure_expr : 需要拼接彙總的列名
  • delimiter : 分隔符,預設NULL
  • ORDER BY XXX : 按照什麼排序

示例

點選檢視程式碼
select province, listagg(city, ',') within GROUP (order by city) as Cities
from (select '四川' province, '成都' city from dual
      union all
      select '四川' province, '綿陽' city from dual
      union all
      select '四川' province, '宜賓' city from dual
      union all
      select '山東' province, '濟南' city from dual
      union all
      select '山東' province, '青島' city from dual
      union all
      select '山東' province, '煙臺' city from dual) temp
group by province

高階用法

listagg(XXX, ',') within GROUP (order by XXX) over (partition by XXX) rank

能夠通過【partition by】按照不同的層級劃分

示例

點選檢視程式碼
select country,
       /* 按照【國家】的層級彙總 */
       listagg(university, ',') within GROUP (order by university) over (partition by country) country_university,
       city,
       /* 按照【城市】的層級彙總 */
       listagg(university, ',') within GROUP (order by university) over (partition by city)    city_university
from (select '中國' country, '北京' city, '北京大學' university from dual union all
      select '中國' country, '北京' city, '清華大學' university from dual union all
      select '中國' country, '上海' city, '同濟大學' university from dual union all
      select '中國' country, '上海' city, '同濟大學' university from dual union all
      select '英國' country, '倫敦' city, '倫敦商學院' university from dual union all
      select '英國' country, '倫敦' city, '金斯頓大學' university from dual union all
      select '英國' country, '牛津' city, '牛津大學' university
      from dual) temp

拓展

Mysql group_concat函式

MySQL中也有類似的函式,就是group_concat函式

基本語法

group_concat([DISTINCT] 要連線的欄位 [Order BY 排序欄位 ASC/DESC] [Separator '分隔符'])

示例

點選檢視程式碼
select country,
        /* 按照【國家】的層級彙總 */
       group_concat(DISTINCT university Order BY university Separator ',') universitys
from (select '中國' country, '北京' city ,'北京大學' university from dual union all
      select '中國' country, '北京' city ,'清華大學' university from dual union all
      select '中國' country, '上海' city ,'復旦大學' university from dual union all
      select '中國' country, '上海' city ,'復旦大學' university from dual union all
      select '英國' country, '倫敦' city ,'倫敦商學院' university from dual union all
      select '英國' country, '倫敦' city ,'金斯頓大學' university from dual union all
      select '英國' country, '牛津' city ,'牛津大學' university from dual) temp
	group by country

注意

  • Mysql的group_concat函式是可以去重的,需要結合GROUP BY使用
  • Oracle的Listagg()函式無法進行去重,如果要去重的話,可以使用下列三種方法
    • 使用wm_concat() + distinct去重聚合【oracle官方不太推薦】
    • 使用正則替換方式去重【僅適用於oracle字串大小比較小的情況】
    • 先去重,再聚合【推薦使用】

參考部落格