【问题标题】:Can't use subquery in select statement. Returns "FROM expression missing"不能在 select 语句中使用子查询。返回“缺少 FROM 表达式”
【发布时间】:2020-02-13 01:17:53
【问题描述】:

我正在努力处理 SELECT 语句中的子查询。我收到一个错误,缺少 FROM 表达式 (ORA-00923)。

我希望将计数结果放在一行中,因此我尝试在 SELECT 语句中使用子查询,但似乎 SQL 无法识别子查询中的表。

主 FROM 语句中的子查询本身就可以正常工作。

我不知道问题出在哪里。

SELECT  RETDATA.DATETIME AS "Date",
        (SELECT COUNT(RET.EAN)
         FROM RETDATA RET
         WHERE RET.GOODTYPE = 'A-goods') AS 'A-goods',
        (SELECT COUNT(RET.EAN)
         FROM RETDATA RET
         WHERE RET.GOODTYPE = 'B-goods') AS 'B-goods',
        (SELECT COUNT(RET.EAN)
         FROM RETDATA RET
         WHERE RET.GOODTYPE = 'C-goods') AS 'C-goods',
        (SELECT COUNT(RET.EAN)
         FROM RETDATA RET
         WHERE RET.WAREHOUSE = 'Bring (Norway)') AS 'Norway_returns',
        (SELECT COUNT(RET.EAN)
         FROM RETDATA RET
         WHERE RET.WAREHOUSE = 'Hermes') AS 'Hermes_returns'

FROM            (SELECT  TRUNC(V_D."DateTime") AS DATETIME, 
                 V_D2."ProductReference" AS EAN,
                 CASE WHEN V_D3."Name" = 'OK (A-Item)' THEN 'A-goods'
                 WHEN V_D3."Name" IN ('Used','Dirty') THEN 'B-goods'
                 ELSE 'C-goods' END AS GOODTYPE,
                 V_D6."Name" AS WAREHOUSE

        FROM     REPORT.V_PORTALDATAORDERS_SALESORDER V_P
                 JOIN REPORT.V_DATARETURNS_RETURN V_D ON V_P."OrderNumberExternal"=V_D."OrderReference"
                 JOIN REPORT.V_DATARETURNS_RETURNSTATUS V_D1 ON V_D."ReturnStatusId"=V_D1."Id"
                 JOIN REPORT.V_DATARETURNS_RETURNLINE V_D2 ON V_D."Id"=V_D2."ReturnId"
                 JOIN REPORT.V_DATARETURNS_RETURNCONDITION V_D3 ON V_D2."ReturnConditionId"=V_D3."Id"
                 JOIN REPORT.V_DATAGLOBAL_WORKSTATION V_D5 ON V_D2."WorkstationId"=V_D5."Id"
                 JOIN REPORT.V_DATAGLOBAL_WAREHOUSE V_D6 ON V_D5."WarehouseId"=V_D6."Id" 
        WHERE    V_P."CompanyId" = 3 
        AND      V_D1."Label" in ('Processed', 'New') 
        AND      TRUNC(V_D."DateTimeDone") = TO_CHAR(sysdate-1, 'YYYY-MM-DD')) RETDATA

【问题讨论】:

  • AS 'A-goods', 是无效的 SQL。标识符需要用双引号括起来,而不是单引号。

标签: sql select oracle11g subquery


【解决方案1】:

您似乎想要进行条件聚合,而您的查询相当于使用窗口聚合函数:

SELECT  DATETIME AS "Date",
        COUNT( CASE GOODTYPE WHEN 'A-goods' THEN EAN END ) OVER () AS "A-goods",
        COUNT( CASE GOODTYPE WHEN 'B-goods' THEN EAN END ) OVER () AS "B-goods",
        COUNT( CASE GOODTYPE WHEN 'C-goods' THEN EAN END ) OVER () AS "C-goods",
        COUNT( CASE WAREHOUSE WHEN 'Bring (Norway)' THEN EAN END ) OVER () AS "Norway_returns",
        COUNT( CASE WAREHOUSE WHEN 'Hermes'         THEN EAN END ) OVER () AS "Hermes_returns"

FROM    (SELECT  TRUNC(V_D."DateTime") AS DATETIME, 
                 V_D2."ProductReference" AS EAN,
                 CASE WHEN V_D3."Name" = 'OK (A-Item)' THEN 'A-goods'
                 WHEN V_D3."Name" IN ('Used','Dirty') THEN 'B-goods'
                 ELSE 'C-goods' END AS GOODTYPE,
                 V_D6."Name" AS WAREHOUSE

        FROM     REPORT.V_PORTALDATAORDERS_SALESORDER V_P
                 JOIN REPORT.V_DATARETURNS_RETURN V_D ON V_P."OrderNumberExternal"=V_D."OrderReference"
                 JOIN REPORT.V_DATARETURNS_RETURNSTATUS V_D1 ON V_D."ReturnStatusId"=V_D1."Id"
                 JOIN REPORT.V_DATARETURNS_RETURNLINE V_D2 ON V_D."Id"=V_D2."ReturnId"
                 JOIN REPORT.V_DATARETURNS_RETURNCONDITION V_D3 ON V_D2."ReturnConditionId"=V_D3."Id"
                 JOIN REPORT.V_DATAGLOBAL_WORKSTATION V_D5 ON V_D2."WorkstationId"=V_D5."Id"
                 JOIN REPORT.V_DATAGLOBAL_WAREHOUSE V_D6 ON V_D5."WarehouseId"=V_D6."Id" 
        WHERE    V_P."CompanyId" = 3 
        AND      V_D1."Label" in ('Processed', 'New') 
        AND      V_D."DateTimeDone" >= TRUNC( sysdate-1 )
        AND      V_D."DateTimeDone" <  TRUNC( sysdate )
) RETDATA

但是,您可能正在寻找非窗口聚合函数和 GROUP BY 表达式:

SELECT  DATETIME AS "Date",
        COUNT( CASE GOODTYPE WHEN 'A-goods' THEN EAN END ) AS "A-goods",
        COUNT( CASE GOODTYPE WHEN 'B-goods' THEN EAN END ) AS "B-goods",
        COUNT( CASE GOODTYPE WHEN 'C-goods' THEN EAN END ) AS "C-goods",
        COUNT( CASE WAREHOUSE WHEN 'Bring (Norway)' THEN EAN END ) AS "Norway_returns",
        COUNT( CASE WAREHOUSE WHEN 'Hermes'         THEN EAN END ) AS "Hermes_returns"

FROM    (SELECT  TRUNC(V_D."DateTime") AS DATETIME, 
                 V_D2."ProductReference" AS EAN,
                 CASE WHEN V_D3."Name" = 'OK (A-Item)' THEN 'A-goods'
                 WHEN V_D3."Name" IN ('Used','Dirty') THEN 'B-goods'
                 ELSE 'C-goods' END AS GOODTYPE,
                 V_D6."Name" AS WAREHOUSE

        FROM     REPORT.V_PORTALDATAORDERS_SALESORDER V_P
                 JOIN REPORT.V_DATARETURNS_RETURN V_D ON V_P."OrderNumberExternal"=V_D."OrderReference"
                 JOIN REPORT.V_DATARETURNS_RETURNSTATUS V_D1 ON V_D."ReturnStatusId"=V_D1."Id"
                 JOIN REPORT.V_DATARETURNS_RETURNLINE V_D2 ON V_D."Id"=V_D2."ReturnId"
                 JOIN REPORT.V_DATARETURNS_RETURNCONDITION V_D3 ON V_D2."ReturnConditionId"=V_D3."Id"
                 JOIN REPORT.V_DATAGLOBAL_WORKSTATION V_D5 ON V_D2."WorkstationId"=V_D5."Id"
                 JOIN REPORT.V_DATAGLOBAL_WAREHOUSE V_D6 ON V_D5."WarehouseId"=V_D6."Id" 
        WHERE    V_P."CompanyId" = 3 
        AND      V_D1."Label" in ('Processed', 'New') 
        AND      V_D."DateTimeDone" >= TRUNC( sysdate-1 )
        AND      V_D."DateTimeDone" <  TRUNC( sysdate )
) RETDATA
GROUP BY DATETIME

注意:您似乎也在比较 TRUNC( V_D."DateTimeDone" )TO_CHAR( sysdate-1, 'YYYY-MM-DD' );不要这样做,因为一个是 DATE,另一个是字符串数据类型,Oracle 将使用 NLS_DATE_FORMAT 会话参数将字符串隐式转换回日期,每个用户都可以更改在他们自己的会话中,这将使您对该用户的查询失败。而是在当前日期使用TRUNC

注意 2:AS 'A-goods' 不是有效的别名声明;你想使用双引号而不是单引号。

【讨论】:

    【解决方案2】:

    你可以试试下面的查询-

    SELECT  RETDATA.DATETIME AS "Date",
            COUNT(CASE WHEN GOODTYPE = 'A-goods' THEN EAN) AS 'A-goods',
            COUNT(CASE WHEN GOODTYPE = 'B-goods' THEN EAN) AS 'B-goods',
            COUNT(CASE WHEN GOODTYPE = 'C-goods' THEN EAN) AS 'C-goods',,
            COUNT(CASE WHEN WAREHOUSE = 'Bring (Norway)' THEN EAN) AS 'Norway_returns',
            COUNT(CASE WHEN WAREHOUSE = 'Hermes' THEN EAN) AS 'Hermes_returns'
    FROM (SELECT  TRUNC(V_D."DateTime") AS DATETIME, 
                  V_D2."ProductReference" AS EAN,
                  CASE WHEN V_D3."Name" = 'OK (A-Item)' THEN 'A-goods'
                       WHEN V_D3."Name" IN ('Used','Dirty') THEN 'B-goods'
                       ELSE 'C-goods' END AS GOODTYPE,
                  V_D6."Name" AS WAREHOUSE
          FROM REPORT.V_PORTALDATAORDERS_SALESORDER V_P
          JOIN REPORT.V_DATARETURNS_RETURN V_D ON V_P."OrderNumberExternal" = V_D."OrderReference"
          JOIN REPORT.V_DATARETURNS_RETURNSTATUS V_D1 ON V_D."ReturnStatusId" = V_D1."Id"
          JOIN REPORT.V_DATARETURNS_RETURNLINE V_D2 ON V_D."Id" = V_D2."ReturnId"
          JOIN REPORT.V_DATARETURNS_RETURNCONDITION V_D3 ON V_D2."ReturnConditionId" = V_D3."Id"
          JOIN REPORT.V_DATAGLOBAL_WORKSTATION V_D5 ON V_D2."WorkstationId" = V_D5."Id"
          JOIN REPORT.V_DATAGLOBAL_WAREHOUSE V_D6 ON V_D5."WarehouseId" = V_D6."Id" 
          WHERE V_P."CompanyId" = 3 
          AND V_D1."Label" in ('Processed', 'New') 
          AND TRUNC(V_D."DateTimeDone") = TO_CHAR(sysdate-1, 'YYYY-MM-DD')) RETDATA
    GROUP BY DATETIME
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多