Oracle SQL LISTAGG函数-包括多个值

ui7jx7zq  于 2023-08-03  发布在  Oracle
关注(0)|答案(3)|浏览(116)

是否可以在LISTAGG中包含针对每个值的计数?
例如,当前结果使用

SELECT 
CLIENT, 
AIRLINE, 
COUNT(DISTINCT CUSTOMER_ID) AS DISTINCT_CUSTOMER, 
COUNT(ORDER_ID) AS NO_ORDERS, 
LISTAGG(DISTINCT(FLIGHT), ', ') 
   WITHIN GROUP BY (ORDER BY FLIGHT) AS FLIGHT
GROUP BY CLIENT, AIRLINE

CLIENT        AIRLINE      DISTINCT_customers    NO_ORDERS   FLIGHT
ABC           Qantas       18038                 26000       QF123, QF456, QF789

字符串
预期成果

CLIENT        AIRLINE      DISTINCT_customers    NO_ORDERS   FLIGHT
ABC           Qantas       18038                 26000       QF123 (3), QF456 (10), QF789 (10)

rxztt3cl

rxztt3cl1#

我会使用两个步骤:一个是获取数据 * 而不带 * listagg,然后在最后一步中将其应用于该结果。
例如(基于Scott的emp表):

SQL> select deptno, job, count(*) cnt
  2  from emp
  3  group by deptno, job;

    DEPTNO JOB              CNT
---------- --------- ----------
        20 CLERK              2
        30 SALESMAN           4
        20 MANAGER            1
        30 CLERK              1
        10 PRESIDENT          1
        30 MANAGER            1
        10 CLERK              1
        10 MANAGER            1
        20 ANALYST            2

9 rows selected.

字符串
前面的查询用作CTE(名为temp),listagg包含job沿着执行该工作的员工数量(这是count返回的):

SQL> with temp as
  2    (select deptno, job, count(*) cnt
  3     from emp
  4     group by deptno, job
  5    )
  6  select deptno,
  7    listagg(job ||' ('|| cnt ||')', ', ') within group (order by job) result
  8  from temp
  9  group by deptno;

    DEPTNO RESULT
---------- --------------------------------------------------
        10 CLERK (1), MANAGER (1), PRESIDENT (1)
        20 ANALYST (2), CLERK (2), MANAGER (1)
        30 CLERK (1), MANAGER (1), SALESMAN (4)

SQL>


应用于您的查询(种无效; miss the from clause),它会是这样的:

WITH
   temp
   AS
      (  SELECT client,
                airline,
                COUNT (DISTINCT customer_id) AS distinct_customer,
                COUNT (order_id) AS no_orders,
                flight
           FROM your_table
       GROUP BY client, airline, flight)
  SELECT client,
         airline,
         distinct_customer,
         LISTAGG (flight || ' (' || no_orders || ')', ', ') WITHIN GROUP (ORDER BY NULL) AS flight
    FROM temp
GROUP BY client, airline, distinct_customer;

wljmcqd8

wljmcqd82#

由于您希望获得每个客户端、航空公司和航班的计数,以及每个客户端和航空公司的不同客户,因此需要加入两个单独的聚合。
下面是一个逐步执行此操作的查询:

with per_flight as
(
  select client, airline, flight, count(*) as no_orders
  from orders
  group by client, airline, flight
)
, per_airline1 as
(
  select
    client, airline,
    listagg(flight || '(' || no_orders || ')', ', ') 
       within group by (order by flight) as flights
  from per_flight
  group by client, airline
)
, per_airline2 as
(
  select
    client, airline,
    count(distinct customer_id) as distinct_customer,
    count(*) as no_orders
  from orders
  group by client, airline
)
select
  client, airline,
  per_airline2.distinct_customer,
  per_airline2.no_orders,
  per_airline1.flights
from per_airline1
join per_airline2 using (client, airline);

字符串

pkwftd7m

pkwftd7m3#

您可以对每个航班进行聚合,然后再次聚合:

SELECT client,
       airline,
       ( SELECT COUNT(DISTINCT customer_id)
         FROM   table_name c
         WHERE  t.client = c.client
         AND    t.airline = c.airline ) AS distinct_customer,
       SUM(no_orders) AS no_orders,
       LISTAGG(flight || ' (' || no_flights || ')', ',')
         WITHIN GROUP (ORDER BY flight) AS flight
FROM   (
  SELECT client,
         airline,
         flight,
         COUNT(order_id) AS no_orders,
         COUNT(something) AS no_flights -- you do not provide sample data so we do not know
                                        -- what we should count here.
  FROM   table_name
  GROUP BY
         client,
         airline,
         flight
) t
GROUP BY
       client,
       airline

字符串

  • 注意:在最内层的查询中查找DISTINCT客户的计数,然后在外层查询中查找SUM将是不正确的,因为您可以让同一客户使用同一客户和航空公司的不同航班,然后当您在外层查询中合计时,您将重复计算该客户。相反,您需要使用相关子查询或连接到另一个子查询,在其中找到不同的客户。

相关问题