SQL是否有比基于不同标准的CASE结果更有效的方法

问题描述 投票:1回答:3

以下case语句似乎不是我想要的结果的最佳或最有效的方法。

结果必须在1字段中的1行上,如下结果所示。如果有1个PO和1个IREQ,则结果应在LINE_COMMENT字段的行上显示“ 1 PO,1 IREQ”。如果只有2个PR,则结果应在LINE_COMMENT字段的行上显示“ 2 PR”。此过程将重复大约65K次,结果会有所不同。

今天的一行明天可能会根据数据更改重新查询(例如,今天的结果可能是“ 1 PO,2 PR”,明天的行结果可能是“ 2 PO”。

另外,PO计数来自其自己的表,而PR和IREQ来自另一个表,并且两个表都连接到具有2个唯一键的另一个表。

作为一名新的自学成才的分析师,我只尝试过Case陈述。请告知是否有更有效的方法来处理此问题,尤其是因为完整查询将处理约30种不同的组合。

下面是根据特定条件查找数据所需的较大语句的示例。

CASE
    WHEN COUNT PO >= 1 THEN
        CASE
            WHEN COUNT PR >= 1 THEN
                CASE
                    WHEN COUNT IREQ >= 1 THEN
                        PO, PR, IREQ
                    ELSE
                        PO, PR
                END
            WHEN COUNT IREQ >= 1 THEN
                    PO, IREQ
            ELSE
                PO  
            END
    WHEN COUNT PR >= 1 THEN 
        CASE
            WHEN COUNT IREQ >= 1 THEN
                PR, IREQ
            ELSE
                PR
        END
    WHEN COUNT IREQ >= 1 THEN
        IREQ
END LINE_COMMENT

PO  PR  IREQ    RESULT for LINE_COMMENT
1   3   1       1 PO, 3 PR, 1 IREQ
2   1   0       2 PO, 1 PR
1   0   1       1 PO, 1IREQ
1   0   0       1 PO 
0   2   1       2 PR, 1 IREQ 
0   1   0       1 PR 
0   0   2       2 IREQ 
0   0   0       NO RESULTS
sql oracle
3个回答
1
投票

不太漂亮,但是可以(有点)。

placeholder在这里只是为了从视觉上将ireqline_comment分开。

尽管CASE是一个更好的选择,但是decode此情况中更易于使用。

SQL> with test (po, pr, ireq) as
  2    (select 1, 3, 1 from dual union all
  3     select 2, 1, 0 from dual union all
  4     select 1, 0, 1 from dual union all
  5     select 1, 0, 0 from dual union all
  6     select 0, 2, 1 from dual union all
  7     select 0, 1, 0 from dual union all
  8     select 0, 0, 2 from dual union all
  9     select 0, 0, 0 from dual
 10    )
 11  select po, pr, ireq, '->  ' placeholder,
 12         case when po = 0 and pr = 0 and ireq = 0 then 'NO RESULTS'
 13              else decode(po  , 0, null, po || ' PO') ||
 14                   decode(pr  , 0, null, decode(po, 0, null, ', ') || pr || ' PR') ||
 15                   decode(ireq, 0, null, decode(pr, 0, decode(po, 0, null, ', '), ', ') || ireq || ' IREQ')
 16         end line_comment
 17  from test;

        PO         PR       IREQ PLAC LINE_COMMENT
---------- ---------- ---------- ---- ----------------------------------------
         1          3          1 ->   1 PO, 3 PR, 1 IREQ
         2          1          0 ->   2 PO, 1 PR
         1          0          1 ->   1 PO, 1 IREQ
         1          0          0 ->   1 PO
         0          2          1 ->   2 PR, 1 IREQ
         0          1          0 ->   1 PR
         0          0          2 ->   2 IREQ
         0          0          0 ->   NO RESULTS

8 rows selected.

SQL>

0
投票

在Oracle中,您可以表示为:

select replace(trim(',' from
                     (case when po > 0 then po || ' PO, ' else ', ' end) ||
                     (case when pr > 0 then pr || ' PR, ' else ', ' end) ||
                     (case when ireq > 0 then po || ' IREQ, ' else ', ' end) 
                    ), ',', ', '
             ) as line_comment

0
投票

或者也许您想要解码:

select decode(po, 0, '', TO_CHAR(po) || ' PO, ') 
       || decode(pr, 0, '', TO_CHAR(pR) || ' PR, ') 
       || decode(ireq, 0, '', TO_CHAR(ireq) || ' IREQ ') LINE_COMMENT
from test;

这里是DEMO

结果:

LINE_COMMENT
1 PO, 3 PR, 1 IREQ 
2 PO, 1 PR, 
1 PO, 1 IREQ 
1 PO, 
2 PR, 1 IREQ 
1 PR, 
2 IREQ 

@ Littlefoot发表评论后,我将其更改为:

select decode(LINE_COMMENT, '', 'NO RESULTS', rtrim(LINE_COMMENT,','))  LINE_COMMENT
from (
select decode(po, 0, '', TO_CHAR(po) || ' PO,') 
       || decode(pr, 0, '', TO_CHAR(pR) || ' PR,') 
       || decode(ireq, 0, '', TO_CHAR(ireq) || ' IREQ') LINE_COMMENT
from test);

DEMO

结果:

LINE_COMMENT
1 PO,3 PR,1 IREQ
2 PO,1 PR
1 PO,1 IREQ
1 PO
2 PR,1 IREQ
1 PR
2 IREQ
NO RESULTS
© www.soinside.com 2019 - 2024. All rights reserved.