格式化连接查询的输出

Format the output of Join Query

我有一个给出以下输出的连接查询。

SELECT DISTINCT LOC.STATE, ORD.* FROM 
( 
    SELECT COUNT (*) ORDERS, 
    ORDV.PERSON_ID PERSON_ID,
    PERSON.FIRST_NAME FN,
    PERSON.LAST_NAME LN,
    SOURCE 
    FROM MY_ORD_V ORDV, EIM_PERSON PERSON
    WHERE ORD_STATUS_ID NOT IN (A, C, D, F)
         AND PERSON.PERSON_ID = ORDV.PERSON_ID
         GROUP BY ORDV.PERSON_ID,
         SOURCE,
         PERSON.FIRST_NAME,
         PERSON.LAST_NAME
    ORDER BY 1 ASC
) ORD , MY_LOCATION_V LOC
    WHERE ORD.PERSON_ID = LOC.OBJ_ID ORDER BY LOC.STATE, ORD.FN, ORD.LN

当前输出和预期输出:

从 Oracle 11g 开始,您现在拥有 LISTAGG analytic function。这可能是您正在寻找的(我用于测试的演示 SQL):

SELECT DISTINCT state, LISTAGG(TO_CHAR(orders)||src, '|') WITHIN GROUP (ORDER BY fn, ln) OVER (PARTITION BY state, fn, ln) as orders
     , fn
     , ln
FROM (
SELECT 'NY' as state, 2 as orders, 'GREG' as fn, 'BOOTINE' as ln, 'DBS' as src from dual
union all
SELECT 'NY' as state, 3 as orders, 'GREG' as fn, 'BOOTINE' as ln, 'PST' as src from dual
union all
SELECT 'MA' as state, 2 as orders, 'ANN' as fn, 'SILVEST' as ln, 'DBS' as src from dual
union all
SELECT 'MA' as state, 2 as orders, 'ANN' as fn, 'SILVEST' as ln, 'PST' as src from dual
)

使用你的 SQL 它会是这样的:

SELECT DISTINCT state
     , LISTAGG(TO_CHAR(orders)||src, '|') WITHIN GROUP (ORDER BY fn, ln) OVER (PARTITION BY state, fn, ln) as orders
     , fn
     , ln
FROM ( 
    SELECT COUNT (*) ORDERS, 
    ORDV.PERSON_ID PERSON_ID,
    PERSON.FIRST_NAME FN,
    PERSON.LAST_NAME LN,
    SOURCE 
    FROM MY_ORD_V ORDV, EIM_PERSON PERSON
    WHERE ORD_STATUS_ID NOT IN (A, C, D, F)
         AND PERSON.PERSON_ID = ORDV.PERSON_ID
         GROUP BY ORDV.PERSON_ID,
         SOURCE,
         PERSON.FIRST_NAME,
         PERSON.LAST_NAME
    ORDER BY 1 ASC
) ORD , MY_LOCATION_V LOC
    WHERE ORD.PERSON_ID = LOC.OBJ_ID 
  ORDER BY LOC.STATE, ORD.FN, ORD.LN

这是一个替代版本,只是一个展示想法的伪查询。您可以在 oracle 中与 || 连接。像这样,您将始终拥有两个来源,当计数为 0 时也是如此。如果来源需要是动态的,您仍然可以通过在子查询中获取所有不同的来源(然后使用 grouplistagg 正如@Patrick Marchand 所说)。

SELECT
  p.state,
  p.first_name,
  p.last_name,
  ( SELECT COUNT(*)
    FROM orders o
    WHERE o.person_id = p.person_id AND o.source = 'DBS'
  ) dbs_count,
  ( SELECT COUNT(*)
    FROM orders o
    WHERE o.person_id = p.person_id AND o.source = 'PST'
  ) pst_count
FROM
  person p
ORDER BY
  p.state, p.first_name, p.last_name