甲骨文解码与案例。查询 return 个不同的结果集
Oracle DECODE vs. CASE. Queries return different result sets
我有以下两个版本的 SQL 声明。一个使用 DECODE 另一个 CASE。其他一切都一样。 DECODE 按预期工作,而 CASE 提供不同的输出(基本上是具有相应访问权限的组)。这是什么原因?
两者都可以在客户端中 运行,不依赖于数据库架构。只有使用 DECODE 或 CASE 的子查询不同,其他部分都相同。
欢迎任何建议!
输出解码:
输出案例:
解码(短)
...
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
...
CASE 短
...
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
...
解码完整
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;
案例完整
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;
不同之处在于与 null 比较时的行为不同:
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
------------------------
第二个查询 return NULL 而不是 1,因此当 x 为 NULL 时 'case x when null then 1 end' 不会 return 1,而这有效:
SQL> select case when null is null then 1 end from dual;
CASEWHENNULLISNULLTHEN1END
--------------------------
1
我有以下两个版本的 SQL 声明。一个使用 DECODE 另一个 CASE。其他一切都一样。 DECODE 按预期工作,而 CASE 提供不同的输出(基本上是具有相应访问权限的组)。这是什么原因?
两者都可以在客户端中 运行,不依赖于数据库架构。只有使用 DECODE 或 CASE 的子查询不同,其他部分都相同。
欢迎任何建议!
输出解码:
输出案例:
解码(短)
...
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
...
CASE 短
...
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
...
解码完整
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;
案例完整
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;
不同之处在于与 null 比较时的行为不同:
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
------------------------
第二个查询 return NULL 而不是 1,因此当 x 为 NULL 时 'case x when null then 1 end' 不会 return 1,而这有效:
SQL> select case when null is null then 1 end from dual;
CASEWHENNULLISNULLTHEN1END
--------------------------
1