Невозможно использовать подзапрос в операторе выбора. Возвращает «ОТ выражения отсутствует» - PullRequest
0 голосов
/ 16 октября 2019

Я борюсь с подзапросом в инструкции 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

Ответы [ 2 ]

1 голос
/ 16 октября 2019

Вы, кажется, хотите выполнить условное агрегирование, и ваш запрос эквивалентен использованию оконных функций агрегирования:

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' не является допустимым объявлением псевдонима;Вы хотите использовать двойные кавычки вместо одинарных.

0 голосов
/ 16 октября 2019

Вы можете попробовать ниже запрос -

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
...