首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >甲骨文解码与案例。查询返回不同的结果集。

问甲骨文解码与案例。查询返回不同的结果集。
EN

Stack Overflow用户
提问于 2020-03-19 11:18:26
回答 1查看 356关注 0票数 1

我有以下两个版本的SQL语句。一种使用解码另一种情况。其他的一切都一样。解码按预期工作,而CASE提供不同的输出(基本上是具有相应访问权限的组)。原因何在?

两者都可以在客户机中运行,不依赖于DB架构。只有使用解码或大小写的子查询是不同的,所有其他部分都是相等的。

欢迎任何建议!

输出解码:

​

输出案例:

​

译码(短)

代码语言:javascript
复制
...
SELECT    principal
         || DECODE (MAX (DECODE ("ON", 'N', permission)),
                    NULL, MAX (DECODE ("ON", 'O', permission)),
                    MAX (DECODE ("ON", 'N', permission)))    latest_permission,
            principal
         || DECODE (MAX (DECODE ("ON", 'O', permission)),
                    NULL, MAX (DECODE ("ON", 'N', permission)),
                    MAX (DECODE ("ON", 'O', permission)))    dont_overwrite_existing
    FROM
...

病例短

代码语言:javascript
复制
...
SELECT    principal
     || CASE MAX (
                 CASE "ON" WHEN 'N' THEN permission END)
            WHEN NULL
            THEN
                MAX (
                    CASE "ON"
                        WHEN 'O' THEN permission
                    END)
            ELSE
                MAX (
                    CASE "ON"
                        WHEN 'N' THEN permission
                    END)
        END    latest_permission,
        principal
     || CASE MAX (
                 CASE "ON" WHEN 'O' THEN permission END)
            WHEN NULL
            THEN
                MAX (
                    CASE "ON"
                        WHEN 'N' THEN permission
                    END)
            ELSE
                MAX (
                    CASE "ON"
                        WHEN 'O' THEN permission
                    END)
        END    dont_overwrite_existing

FROM 
...

解码全

代码语言:javascript
复制
WITH
    old
    AS
        (SELECT REGEXP_SUBSTR (acl, '[^\(]+')     principal,
                REGEXP_SUBSTR (acl, '\(.+')       permission
           FROM (    SELECT REGEXP_SUBSTR (
                                ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4((R)',
                                '[^,]+',
                                1,
                                LEVEL)    acl
                       FROM DUAL
                      WHERE ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4((R)'
                                IS NOT NULL
                 CONNECT BY REGEXP_SUBSTR (
                                ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4((R)',
                                '[^,]+',
                                1,
                                LEVEL)
                                IS NOT NULL)),
    new
    AS
        (SELECT REGEXP_SUBSTR (acl, '[^\(]+')     principal,
                REGEXP_SUBSTR (acl, '\(.+')       permission
           FROM (    SELECT REGEXP_SUBSTR (':Group1(R),:Group1(RW),:GroupA(RWDA),:Group5(R)',
                                           '[^,]+',
                                           1,
                                           LEVEL)    acl
                       FROM DUAL
                      WHERE ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4(R)'
                                IS NOT NULL
                 CONNECT BY REGEXP_SUBSTR (
                                ':Group1(R),:Group1(RW),:GroupA(RWDA),:Group5(R)',
                                '[^,]+',
                                1,
                                LEVEL)
                                IS NOT NULL)),
    principalsToDelete
    AS
        (SELECT DISTINCT REGEXP_SUBSTR (acl, '[^\(]+')     principal
           FROM (    SELECT REGEXP_SUBSTR (NULL,
                                           '[^,]+',
                                           1,
                                           LEVEL)    acl
                       FROM DUAL
                      WHERE NULL IS NOT NULL
                 CONNECT BY REGEXP_SUBSTR (NULL,
                                           '[^,]+',
                                           1,
                                           LEVEL)
                                IS NOT NULL))
  SELECT    principal
         || DECODE (MAX (DECODE ("ON", 'N', permission)),
                    NULL, MAX (DECODE ("ON", 'O', permission)),
                    MAX (DECODE ("ON", 'N', permission)))    latest_permission,
            principal
         || DECODE (MAX (DECODE ("ON", 'O', permission)),
                    NULL, MAX (DECODE ("ON", 'N', permission)),
                    MAX (DECODE ("ON", 'O', permission)))    dont_overwrite_existing
    FROM (SELECT o.*, 'O' "ON"
            FROM old o
          UNION
          SELECT n.*, 'N' "ON"
            FROM new n)
   WHERE principal NOT IN (SELECT principal FROM principalsToDelete)
GROUP BY principal
ORDER BY principal;

病例全

代码语言:javascript
复制
WITH
    old
    AS
        (SELECT REGEXP_SUBSTR (acl, '[^\(]+')     principal,
                REGEXP_SUBSTR (acl, '\(.+')       permission
           FROM (    SELECT REGEXP_SUBSTR (
                                ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4((R)',
                                '[^,]+',
                                1,
                                LEVEL)    acl
                       FROM DUAL
                      WHERE ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4((R)'
                                IS NOT NULL
                 CONNECT BY REGEXP_SUBSTR (
                                ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4((R)',
                                '[^,]+',
                                1,
                                LEVEL)
                                IS NOT NULL)),
    new
    AS
        (SELECT REGEXP_SUBSTR (acl, '[^\(]+')     principal,
                REGEXP_SUBSTR (acl, '\(.+')       permission
           FROM (    SELECT REGEXP_SUBSTR (':Group1(R),:Group1(RW),:GroupA(RWDA),:Group5(R)',
                                           '[^,]+',
                                           1,
                                           LEVEL)    acl
                       FROM DUAL
                      WHERE ':Group1(RWDA),:Group2(RWD),:Group3(RW),:Group4(R)'
                                IS NOT NULL
                 CONNECT BY REGEXP_SUBSTR (
                                ':Group1(R),:Group1(RW),:GroupA(RWDA),:Group5(R)',
                                '[^,]+',
                                1,
                                LEVEL)
                                IS NOT NULL)),
    principalsToDelete
    AS
        (SELECT DISTINCT REGEXP_SUBSTR (acl, '[^\(]+')     principal
           FROM (    SELECT REGEXP_SUBSTR (NULL,
                                           '[^,]+',
                                           1,
                                           LEVEL)    acl
                       FROM DUAL
                      WHERE NULL IS NOT NULL
                 CONNECT BY REGEXP_SUBSTR (NULL,
                                           '[^,]+',
                                           1,
                                           LEVEL)
                                IS NOT NULL))
  SELECT    principal
         || CASE MAX (
                     CASE "ON" WHEN 'N' THEN permission END)
                WHEN NULL
                THEN
                    MAX (
                        CASE "ON"
                            WHEN 'O' THEN permission
                        END)
                ELSE
                    MAX (
                        CASE "ON"
                            WHEN 'N' THEN permission
                        END)
            END    latest_permission,
            principal
         || CASE MAX (
                     CASE "ON" WHEN 'O' THEN permission END)
                WHEN NULL
                THEN
                    MAX (
                        CASE "ON"
                            WHEN 'N' THEN permission
                        END)
                ELSE
                    MAX (
                        CASE "ON"
                            WHEN 'O' THEN permission
                        END)
            END    dont_overwrite_existing

    FROM (SELECT o.*, 'O' "ON"
            FROM old o
          UNION
          SELECT n.*, 'N' "ON"
            FROM new n)
   WHERE principal NOT IN (SELECT principal FROM principalsToDelete)
GROUP BY principal
ORDER BY principal;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-19 12:15:26

这种差异来自与null相比时行为上的差异:

代码语言:javascript
复制
SQL> select decode(null,null,1) from dual;

DECODE(NULL,NULL,1)
-------------------
                  1

SQL> select case null when null then 1 end from dual;

CASENULLWHENNULLTHEN1END
------------------------

第二个查询返回NULL而不是1,因此'case x空时1 end‘在x为空时不返回1,而这是有效的:

代码语言:javascript
复制
SQL> select case when null is null then 1 end from dual;

CASEWHENNULLISNULLTHEN1END
--------------------------
                         1
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60756111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档