【问题标题】:Oracle SQL - Errors ORA-00604 and ORA-00904 - WITH Clause and UNION two queriesOracle SQL - 错误 ORA-00604 和 ORA-00904 - WITH 子句和 UNION 两个查询
【发布时间】:2016-11-25 14:13:12
【问题描述】:
WITH SubQry AS
(SELECT DISTINCT
TBL1."IDNUM"

FROM
"LIBRARY"."SALES" TBL4 INNER JOIN "LIBRARY"."CUSTOMER" TBL1 ON TBL4."CUSTOMERKEY" = TBL1."CUSTOMERKEY"
INNER JOIN  "LIBRARY"."TIME" TBL3 ON TBL4."DATEKEY" = TBL3."DATEKEY"
INNER JOIN "LIBRARY"."PRODUCT" TBL2 ON    TBL4."PRODUCTKEY" = TBL2."PRODUCTKEY"

WHERE
TBL1."COUNTRY" IN ('Austria', 'Denmark',  'Belgium')
AND TBL3."FISCALYEAR" BETWEEN '2011' AND '2016')


SELECT
T1."REGION"
, T1."COUNTRY"
, SubQry."IDNUM" AS "BOOKING_IDNUM"
, (CASE WHEN SubQry."IDNUM" IS NULL Then 'New' ELSE 'Existing' END) "BOOKING_FLAG"
, T1."IDNUM"
, T1."CUSTOMER"
, T1. "BUSSINESS"
, T1."PROJECTNUM"
, T1."PROJECTNAME"
, T1."PROJECTOWNER"
, T1."PROJECT_STATUS"
, SUM(T1."PROJECT_VALUE")
, COUNT(*) "TRANSACTION_COUNT"
, TO_CHAR(trunc(T1."CREATEDATE" / 100)) AS "YEARMONTH_CALENDAR"
, (CASE
WHEN T1."BUSS_ID" IN ('ABC', 'DEF')
THEN 'MID' ELSE NULL END) "DRIVE_TYPE"
, (CASE
WHEN T1."IDNUM" IN ('901023','1401516','2401056','2101444')
THEN 'VIP' ELSE 'Standard' END) AS "ACC_TYPE"
, T1."BUSS_ID"

FROM
"LIBRARY"."PROJECT_DETAILS" T1 LEFT JOIN SubQry  ON  T1."IDNUM" =  SubQry."IDNUM"

WHERE
T1."COUNTRY" IN ('Austria', 'Denmark',  'Belgium')
AND T1."BUSS_ID" IN ('ABC', 'DEF')
AND T1."CREATEDATE" >= '20160101'

GROUP BY
T1."REGION"
, T1."COUNTRY"
, SubQry."IDNUM"
, T1."IDNUM"
, T1."CUSTOMER"
, T1. "BUSSINESS"
, T1."PROJECTNUM"
, T1."PROJECTNAME"
, T1."PROJECTOWNER"
, T1."PROJECT_STATUS"
, T1."BUSS_ID"
, T1."CREATEDATE"

HAVING
SUM(T1."PROJECT_VALUE") > 0


UNION


SELECT
T1."REGION"
, T1."COUNTRY"
, SubQry."IDNUM" AS "BOOKING_IDNUM"
, (CASE WHEN SubQry."IDNUM" IS NULL Then 'New' ELSE 'Existing' END) "BOOKING_FLAG"
, T1."IDNUM"
, T1."CUSTOMER"
, T1."BUSSINESS"
, T1."PROJECTNUM"
, T1."PROJECTNAME"
, T1."PROJECTOWNER"
, T1."PROJECT_STATUS"
, SUM(T1."PROJECT_VALUE")
, COUNT(*) "TRANSACTION_COUNT"
, TO_CHAR(trunc(T1."CREATEDATE" / 100)) AS "CREATEDATE_YEARMONTH_CALENDAR"
, (CASE
WHEN T1."BUSS_ID" IN ('ABC', 'JKL', 'PQR')
THEN 'PRO'ELSE NULL END) "DRIVE_TYPE"
, (CASE
WHEN T1."IDNUM" IN ('901023','1401516','2401056','2101444')
THEN 'VIP' ELSE 'Standard' END) AS "ACC_TYPE"
, T1."BUSS_ID"

FROM
"LIBRARY"."PROJECT_DETAILS" T1 LEFT JOIN SubQry  ON  T1."IDNUM" =  SubQry."IDNUM"

WHERE
T1."COUNTRY" IN ('Austria', 'Denmark',  'Belgium')
AND T1."BUSS_ID" IN ('ABC', 'JKL', 'PQR')
AND T1."CREATEDATE" >= '20160101'

GROUP BY
T1."REGION"
, T1."COUNTRY"
, SubQry."IDNUM"
, T1."IDNUM"
, T1."CUSTOMER"
, T1."BUSSINESS"
, T1."PROJECTNUM"
, T1."PROJECTNAME"
, T1."PROJECTOWNER"
, T1."PROJECT_STATUS"
, T1."BUSS_ID"
, T1."CREATEDATE"

HAVING
SUM(T1."PROJECT_VALUE") > 0

你好,

上述查询包括:

  1. WITH CLAUSE - 本条款的目的是区分 "IDNUM" 与在 2011 年至 2016 年期间购买商品的客户。
  2. 第一次查询 - 查询的主要目的是检查上述 WITH 子句中是否存在任何选定的 "IDNUM"。此外,此查询应该检查选定的 "IDNUM" 是否与特定的 "BUSS_ID" 匹配,并在名为 "DRIVE_TYPE" 的列中将它们标记为 'MID'
  3. 第二个查询 - 此查询与第一个查询的作用几乎相同。唯一的区别是它在名为"DRIVE_TYPE" 的列中将"IDNUM" 标记为'PRO'

您可能已经注意到,在这两个查询中,都有一个共同的"BUSS_ID": 'ABC'

  • 第一次查询 - , (CASE WHEN T1."BUSS_ID" IN ('ABC', 'DEF') THEN 'MID' ELSE NULL END) "DRIVE_TYPE"
  • 第二次查询 - , (CASE WHEN T1."BUSS_ID" IN ('ABC', 'JKL', 'PQR') THEN 'PRO'ELSE NULL END) "DRIVE_TYPE"

我尝试将这些查询联合起来,以将属于“BUSS_ID”的每一行显示为两个单独的结果行。换句话说,如果单行包含"BUSS_ID" of 'ABC',那么 select 语句将显示两次。一行"DRIVE_TYPE" 标记为'MID',另一行标记为'PRO'

问题是,当我运行查询时出现以下错误:

ORA-00604:递归 SQL 级别 1 发生错误

ORA-00904:"from$_subquery$_003"."DATEKEY_0_0": 标识符无效

让我更困惑的是,我可以运行 WHERE CLAUSE + 1st QueryWITH CLAUSE + 2nd Query 的组合 没有任何问题。 但是当我尝试运行 WITH CLAUSE + 1st Query + UNION + 2nd Query 时出现错误。

【问题讨论】:

  • 该查询在 12.1.0.2 上适用于我。你能在其他数据库上重现错误吗?也许您的版本或平台存在错误?它可能有助于创建一个较小的、独立的、可重现的测试用例。
  • @Jon Heller 不幸的是,我只能从数据库中提取数据而不能修改它。但是,您所说的是有效的观点。如果其他事情失败了,我会考虑创建一个测试数据库,但只是作为最后的手段,因为这会花费我太多时间。感谢您抽出时间为我调查这个问题。

标签: sql oracle


【解决方案1】:

这就是 CTE 的伟大之处。尝试用 3 个 CTE 重新编写,我敢打赌,如果你仍然得到一个,错误消息会更好

WITH SubQry AS
(SELECT DISTINCT
TBL1."IDNUM"

FROM
"LIBRARY"."SALES" TBL4 INNER JOIN "LIBRARY"."CUSTOMER" TBL1 ON TBL4."CUSTOMERKEY" = TBL1."CUSTOMERKEY"
INNER JOIN  "LIBRARY"."TIME" TBL3 ON TBL4."DATEKEY" = TBL3."DATEKEY"
INNER JOIN "LIBRARY"."PRODUCT" TBL2 ON    TBL4."PRODUCTKEY" = TBL2."PRODUCTKEY"

WHERE
TBL1."COUNTRY" IN ('Austria', 'Denmark',  'Belgium')
AND TBL3."FISCALYEAR" BETWEEN '2011' AND '2016'), Q1 AS (
   SELECT
   T1."REGION"
   , T1."COUNTRY"
   , SubQry."IDNUM" AS "BOOKING_IDNUM"
   , (CASE WHEN SubQry."IDNUM" IS NULL Then 'New' ELSE 'Existing' END) "BOOKING_FLAG"
   , T1."IDNUM"
   , T1."CUSTOMER"
   , T1. "BUSSINESS"
   , T1."PROJECTNUM"
   , T1."PROJECTNAME"
   , T1."PROJECTOWNER"
   , T1."PROJECT_STATUS"
   , SUM(T1."PROJECT_VALUE")
   , COUNT(*) "TRANSACTION_COUNT"
   , TO_CHAR(trunc(T1."CREATEDATE" / 100)) AS "YEARMONTH_CALENDAR"
   , (CASE
   WHEN T1."BUSS_ID" IN ('ABC', 'DEF')
   THEN 'MID' ELSE NULL END) "DRIVE_TYPE"
   , (CASE
   WHEN T1."IDNUM" IN ('901023','1401516','2401056','2101444')
   THEN 'VIP' ELSE 'Standard' END) AS "ACC_TYPE"
   , T1."BUSS_ID"

   FROM
   "LIBRARY"."PROJECT_DETAILS" T1 LEFT JOIN SubQry  ON  T1."IDNUM" =  SubQry."IDNUM"

   WHERE
   T1."COUNTRY" IN ('Austria', 'Denmark',  'Belgium')
   AND T1."BUSS_ID" IN ('ABC', 'DEF')
   AND T1."CREATEDATE" >= '20160101'

   GROUP BY
   T1."REGION"
   , T1."COUNTRY"
   , SubQry."IDNUM"
   , T1."IDNUM"
   , T1."CUSTOMER"
   , T1. "BUSSINESS"
   , T1."PROJECTNUM"
   , T1."PROJECTNAME"
   , T1."PROJECTOWNER"
   , T1."PROJECT_STATUS"
   , T1."BUSS_ID"
   , T1."CREATEDATE"

   HAVING
   SUM(T1."PROJECT_VALUE") > 0
), Q2 AS
(
  SELECT
  T1."REGION"
  , T1."COUNTRY"
  , SubQry."IDNUM" AS "BOOKING_IDNUM"
  , (CASE WHEN SubQry."IDNUM" IS NULL Then 'New' ELSE 'Existing' END) "BOOKING_FLAG"
  , T1."IDNUM"
  , T1."CUSTOMER"
  , T1."BUSSINESS"
  , T1."PROJECTNUM"
  , T1."PROJECTNAME"
  , T1."PROJECTOWNER"
  , T1."PROJECT_STATUS"
  , SUM(T1."PROJECT_VALUE")
  , COUNT(*) "TRANSACTION_COUNT"
  , TO_CHAR(trunc(T1."CREATEDATE" / 100)) AS "CREATEDATE_YEARMONTH_CALENDAR"
  , (CASE
  WHEN T1."BUSS_ID" IN ('ABC', 'JKL', 'PQR')
  THEN 'PRO'ELSE NULL END) "DRIVE_TYPE"
  , (CASE
  WHEN T1."IDNUM" IN ('901023','1401516','2401056','2101444')
  THEN 'VIP' ELSE 'Standard' END) AS "ACC_TYPE"
  , T1."BUSS_ID"

  FROM
  "LIBRARY"."PROJECT_DETAILS" T1 LEFT JOIN SubQry  ON  T1."IDNUM" =  SubQry."IDNUM"

  WHERE
  T1."COUNTRY" IN ('Austria', 'Denmark',  'Belgium')
  AND T1."BUSS_ID" IN ('ABC', 'JKL', 'PQR')
  AND T1."CREATEDATE" >= '20160101'

  GROUP BY
  T1."REGION"
  , T1."COUNTRY"
  , SubQry."IDNUM"
  , T1."IDNUM"
  , T1."CUSTOMER"
  , T1."BUSSINESS"
  , T1."PROJECTNUM"
  , T1."PROJECTNAME"
  , T1."PROJECTOWNER"
  , T1."PROJECT_STATUS"
  , T1."BUSS_ID"
  , T1."CREATEDATE"

  HAVING
  SUM(T1."PROJECT_VALUE") > 0
)
SELECT * FROM Q1
UNION
SELECT * FROM Q2

还可以考虑将第一个 CTE 更改为使用与 IDNUM 不同的名称,可能是 BOOKING_IDNUM

WITH SubQry AS
(SELECT DISTINCT
TBL1.BOOKING_IDNUM
-- etc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-06
    相关资源
    最近更新 更多