【问题标题】:Oracle SQL - ListAgg - ORA-00923: FROM keyword not found where expectedOracle SQL - ListAgg - ORA-00923:在预期的地方找不到 FROM 关键字
【发布时间】:2019-04-23 11:30:12
【问题描述】:

我有一个如下表结构

PERSON_ID | SUFFIX | Details
-----------------------------
12345     | Mr     | ABC
12345     | Mr     | DEF
12345     | Mr     | GHI

这是我的 SQL

SELECT PERSON_ID
    ,SUFFIX
    ,LISTAGG(Details, ' ') WITHIN
GROUP (
        ORDER BY PERSON_ID
        ) AS Deets
FROM TABLE_NAME
GROUP BY PERSON_ID
    ,SUFFIX

所以我想将多行放入一列。但是,我收到以下错误:

ORA-00923:在预期的地方找不到 FROM 关键字

任何想法为什么会发生这种情况?我的TABLE_NAME 是使用WITH AS 语句构建的。我可以从TABLE_NAME 提取数据就好了,对数据和所有“正常”的东西进行分组

完整代码

WITH
person_id
AS (
    SELECT DISTINCT person_id
    FROM PER_ALL_PEOPLE_F
),

suffix AS (
SELECT person_id, suffix 
FROM PER_PERSON_NAMES_F 
WHERE
    NAME_TYPE = 'GLOBAL' 
     AND TRUNC(SYSDATE) BETWEEN TRUNC(EFFECTIVE_START_date) AND TRUNC(EFFECTIVE_END_DATE) 
GROUP BY person_id, suffix
)
,
person_id_data
AS (
    SELECT DISTINCT person_id
    FROM PER_ALL_ASSIGNMENTS_M
    WHERE person_id IN (SELECT person_id FROM person_id)
    AND ASSIGNMENT_STATUS_TYPE = 'ACTIVE' 
),

-- GETTING NUMBERS
Contact_Phone_Numbers As (SELECT 
    PERSON_ID, 
    OBJECT_VERSION_NUMBER, 
    PHONE_ID, 
    DATE_FROM, 
    DATE_TO, 
    REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(PHONE_TYPE,'O','Other'),'HM','Home Mobile'),'HF','Home Fax'),'H3','Third Home'),'H2','Second Home'),'H1','Home'),'WM','Work Mobile'),'WF','Work Fax'),'W3','Third Work'),'W2','Second Work'),'W1','Work') AS PHONE_TYPE, 
    PHONE_NUMBER, 
    SEARCH_PHONE_NUMBER, 
    COUNTRY_CODE_NUMBER 

FROM 
    PER_PHONES 

WHERE 
    PERSON_ID IN (SELECT person_id FROM person_id_data))
,

NEARLY_THERE AS (
    SELECT A.PERSON_ID, A.PHONE_TYPE, A.PHONE_NUMBER, B.SUFFIX
    FROM Contact_Phone_Numbers A
    LEFT JOIN suffix B
    ON A.PERSON_ID = B.PERSON_ID
    ORDER BY A.PERSON_ID
), 

SO_CLOSE AS (
SELECT PERSON_ID, CONCAT(PHONE_TYPE, CONCAT (' - ' , PHONE_NUMBER)) AS THE_DETAILS, SUFFIX
FROM NEARLY_THERE
ORDER BY PERSON_ID
),

FINAL AS (
    SELECT * FROM SO_CLOSE
)

SELECT PERSON_ID, SUFFIX, LISTAGG(THE_DETAILS, ' ') WITHIN GROUP (ORDER BY PERSON_ID) AS Deets
FROM FINAL 
GROUP BY PERSON_ID, SUFFIX

【问题讨论】:

  • 您的代码运行良好:dbfiddle.uk/…。也许你在实际运行的代码中有一个坏字符。
  • 版本 (12.1.0.2.0) - 在 Oracle Fusion 中使用 Oracle BI
  • 如果删除WITHIN GROUP (ORDER BY PERSON_ID) AS Deets,查询会运行吗?如果您删除LISTAGG 怎么样?
  • @CaiusJard his 版本应该支持WITHIN GROUP 子句就好了。
  • 我知道,我只是想知道它从什么时候开始工作

标签: sql oracle oracle-bi


【解决方案1】:

(这更像是一条评论,但对于实际评论来说太多了/格式化)

如果你运行非 CTE 版本会发生什么?

SELECT 
  paam.person_id, 
  ppnf.suffix,
  LISTAGG(
    CONCAT(
      DECODE(pp.PHONE_TYPE,'O','Other','HM','Home Mobile','HF','Home Fax','H3','Third Home','H2','Second Home','H1','Home','WM','Work Mobile','WF','Work Fax','W3','Third Work','W2','Second Work','W1','Work'),
      ' - ',
      pp.PHONE_NUMBER
    ),
    ' '
  ) WITHIN GROUP (ORDER BY PERSON_ID) as Deets

FROM 
  PER_ALL_ASSIGNMENTS_M paam
  INNER JOIN 
  PER_ALL_PEOPLE_F papf
  ON paam.person_id = papf.person_id

  INNER JOIN 
  PER_PHONES pp
  ON
    paam.person_id = pp.person_id

  LEFT JOIN 
  PER_PERSON_NAMES_F ppnf
  ON 
    paam.PERSON_ID = ppnf.PERSON_ID AND
    ppnf.NAME_TYPE = 'GLOBAL' AND
    TRUNC(SYSDATE) BETWEEN TRUNC(ppnf.EFFECTIVE_START_date) AND TRUNC(ppnf.EFFECTIVE_END_DATE) 

WHERE
  paam.ASSIGNMENT_STATUS_TYPE = 'ACTIVE' 

GROUP BY PERSON_ID, SUFFIX

注意;由于此查询省略了 CTE 表单具有的一些 DISTINCT 操作,因此可能会看到一些小的语法错误和结果差异。我建议你在没有 listagg/group 的情况下修复它,这样就不会出现重复的行(将你的 where 子句/连接条件排序,以便消除笛卡尔积而不是稍后将它们区分开来)

即解决这个问题:

SELECT 
  paam.person_id, 
  ppnf.suffix,

    CONCAT(
      DECODE(pp.PHONE_TYPE,'O','Other','HM','Home Mobile','HF','Home Fax','H3','Third Home','H2','Second Home','H1','Home','WM','Work Mobile','WF','Work Fax','W3','Third Work','W2','Second Work','W1','Work'),
      ' - ',
      pp.PHONE_NUMBER
    )

FROM 
  PER_ALL_ASSIGNMENTS_M paam
  INNER JOIN 
  PER_ALL_PEOPLE_F papf
  ON paam.person_id = papf.person_id

  INNER JOIN 
  PER_PHONES pp
  ON
    paam.person_id = pp.person_id

  LEFT JOIN 
  PER_PERSON_NAMES_F ppnf
  ON 
    paam.PERSON_ID = ppnf.PERSON_ID AND
    ppnf.NAME_TYPE = 'GLOBAL' AND
    TRUNC(SYSDATE) BETWEEN TRUNC(ppnf.EFFECTIVE_START_date) AND TRUNC(ppnf.EFFECTIVE_END_DATE) 

WHERE
  paam.ASSIGNMENT_STATUS_TYPE = 'ACTIVE' 

然后重新引入 LISTAGG

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多