【问题标题】:It is possible to run LISTAGG on a row already grouped?可以在已经分组的行上运行 LISTAGG 吗?
【发布时间】:2015-06-28 23:35:06
【问题描述】:

Oracle 11g R2 通过 SqlDeveloper:

如果该行已经被分组,我如何使用LISTAGG 函数对该行进行分组?返回此错误:ORA-00937: not a single-group group function

CREATE TABLE doc
(name varchar (10), id int, ein int, prim varchar (1), spec varchar (20));
INSERT INTO doc (name, id, ein, prim, spec)
values ('SARAH', 77, 1234, 'Y', 'CARDIOLOGY');
INSERT INTO doc (name, id, ein, prim, spec)
values ('SARAH', 77, 1234, 'Y', 'CARDIOLOGY');
INSERT INTO doc (name, id, ein, prim, spec)
values ('JAMES', 45, 8686, 'Y', 'SURGERY');
INSERT INTO doc (name, id, ein, prim, spec)
values ('JAMES', 45, 9123, 'Y', 'FAMILY');
INSERT INTO doc (name, id, ein, prim, spec)
values ('LISA', 23, 7457, 'N', 'INTERNAL');
INSERT INTO doc (name, id, ein, prim, spec)
values ('LISA', 23, 7457, 'Y', 'SURGERY');
INSERT INTO doc (name, id, ein, prim, spec)
values ('BILL', 11, 6391, 'N', 'PEDIATRICS');
INSERT INTO doc (name, id, ein, prim, spec)
values ('BILL', 11, 6391, 'N', 'PEDIATRICS');
INSERT INTO doc (name, id, ein, prim, spec)
values ('BILL', 11, 6391, 'N', 'PEDIATRICS');
INSERT INTO doc (name, id, ein, prim, spec)
values ('BILL', 11, 6391, 'Y', 'PEDIATRICS');     

NAME     ID     EID     PRIMARY LOCATION     SPEC
BILL     11     6391         N              PEDIATRICS
BILL     11     6391         N              PEDIATRICS
BILL     11     6391         N              PEDIATRICS
BILL     11     6391         Y              PEDIATRICS
JAMES    45     8686         Y               SURGERY
JAMES    45     9123         Y               FAMILY
LISA     23     7457         N               SURGERY
LISA     23     7457         Y               INTERNAL
SARAH    77     1234         Y               CARDIOLOGY
SARAH    77     1234         Y               CARDIOLOGY

结果需要是每个 EIN 的主要位置的计数,以及提供者的专业列表 - 没有重复。

我可以非常接近,但我在 SPEC 列中返回了重复项,因为一些提供商在多个位置具有相同的专业。一些提供商有 15-20 个位置,因此在此列中出现重复可能会非常混乱。

SELECT
  name, id, ein,
  SUM(CASE WHEN prim = 'Y' THEN 1 ELSE 0 END) count,
  LISTAGG(spec, ',') WITHIN GROUP (ORDER BY spec) spec
FROM doc
GROUP BY NAME, ID, EIN
ORDER BY NAME;


    Results:
NAME    ID    EIN    COUNT   SPEC
BILL    11    6391    1      PEDIATRICS,PEDIATRICS,PEDIATRICS,PEDIATRICS
JAMES   45    8686    1      Surgery
JAMES   45    9123    1      FAMILY
LISA    23    7457    1      INTERNAL,SURGERY
SARAH   77    1234    2      CARDIOLOGY,CARDIOLOGY 

对此的大多数解决方案都使用了SELECT DISTINCT 或类似的东西,但我不能排除任何行,因为我需要返回每一行,以便将其包含在主要位置的计数中。

我尝试先将所有内容组合在一起,然后在 SELECT 语句中使用 LISTAGG,但我收到错误消息,我认为这是由于对已分组的行进行了分组。

SELECT
  Name, ID, EIN, COUNT,
  LISTAGG(SPEC, ',') WITHIN GROUP (ORDER BY spec) spec
FROM
(
SELECT 
  NAME, ID, EIN, 
  SUM(CASE WHEN PRIM = 'Y' THEN 1 ELSE 0 END) COUNT, 
  SPEC
FROM DOC
GROUP BY name, id, ein, spec
)
order by name;

【问题讨论】:

    标签: sql oracle-sqldeveloper oracle11gr2 ora-00937 listagg


    【解决方案1】:

    您希望外部查询组合spec 值,因此只需添加一个提及所有其他输出的GROUP BY。另外我认为您可能希望内部 COUNTs 为 SUMmed。

    试试这个 (sqlfiddle)

    SELECT
      Name, ID, EIN, sum(COUNT),
      LISTAGG(SPEC, ',') WITHIN GROUP (ORDER BY spec) spec
    FROM
    (
    SELECT 
      NAME, ID, EIN, 
      SUM(CASE WHEN PRIM = 'Y' THEN 1 ELSE 0 END) COUNT, 
      SPEC
    FROM DOC
    GROUP BY name, id, ein, spec
    )
    GROUP BY name, id, ein
    order by name;
    

    【讨论】:

    • 这太有道理了。这就是为什么我没有想到它。非常感谢!
    猜你喜欢
    • 2019-04-07
    • 2021-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    相关资源
    最近更新 更多