解码在oracle sql查询中不起作用

时间:2012-08-30 10:06:41

标签: sql oracle

我这里使用组函数进行简单查询。这是查询

SELECT DECODE (DIRAPP, NULL, 'SML', DIRAPP) DD
  FROM (SELECT      'At Director Approval '
                 || NVL (COUNT (*), 0)
                 || ' Cheques of Rs. '
                 || NVL (TO_CHAR (SUM (BPV_AMT), '9,999,999,999'), 0)
                 || ' in '
                 || CONCATENATE_LIST
                                 (CURSOR (SELECT DISTINCT NVL
                                                             (BPV_DTE,
                                                              SYSDATE
                                                             ) BPV_DTE
                                                     FROM CHECK_DATA
                                                    WHERE STA_FLG IN (1, 3)
                                                 ORDER BY 1 DESC
                                         )
                                 ) DIRAPP
            FROM CHECK_DATA
           WHERE STA_FLG IN (1, 3)
        GROUP BY 1, 2) A

我已经使用了nvl函数并且还进行了解码但是当没有找到针对标志1和3的数据时,nvl中甚至没有显示任何内容0,也没有显示解码。我想用as {显示整个字符串{1}}请任何人帮我这样做

1 个答案:

答案 0 :(得分:3)

decode没有被破坏,它只是没有数据可以使用。您正在where sta_flg in (1,3)上进行过滤,因此如果没有任何状态的记录,则根本没有行。你无法解码不存在的东西。

解决此问题的一种方法是更改​​计算方式并对值进行求和,以便在select内有效地完成过滤,而不是where。暂时删除格式,而不是执行:

SELECT COUNT(*), SUM(BPV_AMT)
FROM check_data
WHERE sta_flag IN (1,3);

...如果没有匹配标志的记录,将不返回任何行,即使表中有其他数据,您也可以这样做:

SELECT SUM(CASE WHEN sta_flg IN (1,3) THEN 1 ELSE 0 END) AS rec_cnt,
    SUM(CASE WHEN sta_flg IN (1,3) THEN bpv_amt ELSE 0 END) AS bpv_amt_tot
FROM check_data;

只要表格不为空,这将返回单行数据,其中正常值或rec_cntbpv_amt_tot都设置为零。

将其作为内部选择插入您的查询可能如下所示:

SELECT 'At Director Approval '
    || rec_cnt
    || ' Cheques of Rs. '
    || TO_CHAR(bpv_amt_tot, '9,999,999,999')
    || CASE WHEN rec_cnt = 0 THEN NULL
        ELSE ' in ' || CONCATENATE_LIST(CURSOR(
            SELECT DISTINCT NVL(bpv_dte, SYSDATE)
            FROM check_data
            WHERE sta_flg IN (1, 3)
            ORDER BY 1 DESC
        )) END AS dirapp
FROM (
    SELECT SUM(CASE WHEN sta_flg IN (1,3) THEN 1 ELSE 0 END) AS rec_cnt,
        SUM(CASE WHEN sta_flg IN (1,3) THEN bpv_amt ELSE 0 END) AS bpv_amt_tot
    FROM check_data
);

case部分周围的' in ' || CONCATENATE_LIST(...只是为了避免在没有匹配状态时出现跟踪in

由于您未选择任何非聚合列,因此不需要group by子句。 (你所拥有的那个也是不正确的 - 你不能按列位置分组,所以group by 1,2按两个常量值分组,这不会添加任何内容。

最后,因为你正在使用concatenate_list()我假设你的版本早于11gR2;如果您使用当前版本,则内置listagg()会更简单。