【问题标题】:I cant get LISTAGG in Oracle to do as it should?我不能让 Oracle 中的 LISTAGG 做它应该做的事情吗?
【发布时间】:2015-11-17 15:24:33
【问题描述】:

我的数据如下:

MEDIA_ID | CHANNEL_NAME
EH/123A     CH-1
EH/123A     CH-4
EH/132A     CH-5
ES/133B     CH-1
ES/133B     CH-2
ES/133B     CH-5

我想要的是:

EH/123A  |  CH-1,CH-4,CH-5
ES/123B  |  CH-1,CH-2,CH-5

我在 Oracle 中使用这个 SQL:

SELECT DISTINCT 
PR.MEDIA_ID
, LISTAGG(PR.CHANNEL_NAME, ', ') WITHIN GROUP (ORDER BY CHANNEL_NAME) AS PREM_CHAN
FROM PREM_REPORT PR
GROUP BY PR.MEDIA_ITEM, PR.CHANNEL_NAME;

我得到的是:

MEDIA_ID | CHANNEL_NAME
EH/123A     CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1
EH/123A     CH-4,CH-4,CH-4,CH-4,CH-4,CH-4,CH-4,CH-4,CH-4,CH-4,CH-4,CH-4
EH/132A     CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5
ES/133B     CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1,CH-1
ES/133B     CH-2,CH-2,CH-2,CH-2,CH-2,CH-2,CH-2,CH-2,CH-2,CH-2,CH-2,CH-2
ES/133B     CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5,CH-5

想法?

谢谢。 本

【问题讨论】:

  • group by中删除channel_name
  • 并删除 distinct。不需要。

标签: sql oracle listagg


【解决方案1】:

我想你想要的查询是:

SELECT PR.MEDIA_ID,
       LISTAGG(PR.CHANNEL_NAME, ', ') WITHIN GROUP (ORDER BY CHANNEL_NAME) AS PREM_CHAN
FROM PREM_REPORT PR
GROUP BY PR.MEDIA_ITEM;

也就是说,从您的查询中删除 PR.CHANNEL_NAME。我不确定您为什么会通过您提供的查询获得结果。也许select distinctgroup by 之间存在一些奇怪的交互。你几乎从不使用select distinctgroup by

编辑:

要在LIST_AGG() 中返回不同的值,您需要使用子查询。在这种情况下,一个简单的方法是:

SELECT PR.MEDIA_ID,
       LISTAGG(PR.CHANNEL_NAME, ', ') WITHIN GROUP (ORDER BY CHANNEL_NAME) AS PREM_CHAN
FROM (SELECT DISTINCT MEDIA_ID, CHANNEL_NAME
      FROM PREM_REPORT PR
     ) PR
GROUP BY PR.MEDIA_ITEM;

【讨论】:

  • 谢谢,您是否还知道如何确保仅在 Listagg 中返回 Distinct 值? (我的数据量很大,但简单地说,我可能出于某种原因有重复的行)
  • 非常感谢,我搞错了.. :-)
【解决方案2】:

您可以删除GROUP BY,然后添加PARTITION BY

SELECT DISTINCT PR.MEDIA_ID
   ,LISTAGG(PR.CHANNEL_NAME, ', ') 
   WITHIN GROUP (ORDER BY CHANNEL_NAME) OVER (PARTITION BY  PR.MEDIA_ID) AS PREM_CHAN
FROM PREM_REPORT PR;

SqlFiddleDemo

输出:

╔═══════════╦══════════════════╗
║ MEDIA_ID  ║    PREM_CHAN     ║
╠═══════════╬══════════════════╣
║ ES/133B   ║ CH-1, CH-2, CH-5 ║
║ EH/123A   ║ CH-1, CH-4, CH-5 ║
╚═══════════╩══════════════════╝

【讨论】:

  • 谢谢你,我已经记下了 PARTITION。 B
【解决方案3】:

我认为你把 GROUP BY 弄错了。这对我有用。

WITH prem_report AS (
  SELECT 'EH/123A' media_id, 'CH-1' channel_name FROM DUAL
  UNION
  SELECT 'EH/123A' media_id, 'CH-4' channel_name FROM DUAL
  UNION
  SELECT 'EH/132A' media_id, 'CH-5' channel_name FROM DUAL
  UNION
  SELECT 'ES/133B' media_id, 'CH-1' channel_name FROM DUAL
  UNION
  SELECT 'ES/133B' media_id, 'CH-2' channel_name FROM DUAL
  UNION
  SELECT 'ES/133B' media_id, 'CH-5' channel_name FROM DUAL
)
SELECT DISTINCT pr.media_id, LISTAGG(pr.channel_name, ', ') WITHIN GROUP     (ORDER BY channel_name) AS prem_chan
FROM prem_report pr
GROUP BY pr.media_id

【讨论】:

    猜你喜欢
    • 2019-01-06
    • 1970-01-01
    • 1970-01-01
    • 2011-09-28
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多