将多行SQL响应合并为一行并重命名值

时间:2018-08-09 15:10:48

标签: sql oracle listagg

例如,我有一个查询...

SELECT a.order_number, b.state
from tableone a
tabletwo b
WHERE
1=1
AND a.id = b.id
AND a.order_number = '12345';

这将输出:

order_number    state
12345             CA
12345             AZ
12345             NY

我正在寻找而不是让它返回连接的行,所以我可以将此结果保持为一行。

order_number       state
12345                 CA,AZ,NY

所以我建立了这个:

SELECT
a.order_number, 
LISTAGG(b.state, ',') WITHIN GROUP (ORDER BY a.order_number) AS states
from tableone a
tabletwo b
WHERE
1=1
AND a.id = b.id
AND a.order_number = '12345'
GROUP BY a.order_number;    

现在-我的问题是-如何为这些状态分配值?只有3个-CA,AZ和NY,其中CA = 1,AZ = 2和NY =3。我要么必须执行此逻辑,才能与另一个使用这些数值表示状态的应用程序同步。 SQL或后端的另一个系统中,如果可能的话,我宁愿在这里进行操作...

我希望输出看起来像这样:

order_number       state
12345                 1,2,3

1 个答案:

答案 0 :(得分:1)

如果您必须对转换进行硬编码,并且没有将状态码转换为数字的查找表,则可以使用一个case表达式:

CASE b.state WHEN 'CA' THEN 1 WHEN 'AZ' THEN 2 WHEN 'NY' THEN 3 END

可在LISTAGG()调用中使用:

SELECT
  a.order_number, 
  LISTAGG(CASE b.state WHEN 'CA' THEN 1 WHEN 'AZ' THEN 2 WHEN 'NY' THEN 3 END, ',')
    WITHIN GROUP (ORDER BY a.order_number) AS states
FROM tableone a
JOIN tabletwo b
ON a.id = b.id
WHERE
1=1
AND a.order_number = '12345'
GROUP BY a.order_number;    

ORDER_NUMBER STATES              
------------ --------------------
12345        1,2,3               

顺便说一句,我已经自由地切换到正确的连接语法。同样,order by子句在按该值分组时实际上并没有做任何事情,因此在该组中它始终是相同的。如果顺序很重要,则需要将其更改-可能更改为相同的case表达式。