Страница 1 из 1

Проблема с агрегатом

Добавлено: 27 сен 2006, 11:16
Лысый
FB 1.5.3

Есть запрос:

Код: Выделить всё

SELECT CASE WHEN P.CODE_TYPE = 1 THEN '1. Зубопротезирование'
            WHEN P.CODE_TYPE = 2 THEN '2. Слухопротезирование'
            ELSE '3. Не определено' END AS CODE_TYPE
     , O.NAME AS REGION
     , H.ID_HOSPITAL
     , MAX(H.SHORT_NAME) AS HOSPITAL
     , SUM(CASE WHEN RE.ID_PARENT IS NOT NULL AND RD.ID_DEFECT IS NULL
                THEN 0 ELSE RE.STO END) AS SUM_TOTAL
     , (SUM(CASE WHEN RE.IS_DEFECT_T = 1 THEN RE.STO ELSE 0 END) -

       SUM(CASE WHEN RE.ID_PARENT IS NOT NULL AND RD.ID_DEFECT IS NULL
                THEN RE.STO ELSE 0 END)) AS SUM_DEFECT_T

     , SUM(CASE WHEN RE.IS_DEFECT_M = 1 THEN RE.SUM_DEFECT_M ELSE 0 END) AS SUM_DEFECT_M
     , SUM(CASE WHEN RDM.SUM_DEFECT IS NULL THEN 0 ELSE RDM.SUM_DEFECT END) AS SUM_DEFECT_M2
     , SUM(RE.SUM_PAY - CASE WHEN RDM.SUM_DEFECT IS NULL THEN 0 ELSE RDM.SUM_DEFECT END)  AS SUM_PAY
     , (SELECT SUM(PM.SUM_PAY)
          FROM PAYMENT PM JOIN HOSPITAL_CONTRACT HC ON (PM.ID_HOSPITAL_CONTRACT = HC.ID_HOSPITAL_CONTRACT)
         WHERE PM.ID_HOSPITAL = H.ID_HOSPITAL
           AND PM.D_DOCUMENT <= :D_END
           AND HC.CODE_TYPE = P.CODE_TYPE) AS SUM_PAYMENT
  FROM HOSPITAL H
       JOIN ROLL R ON (H.ID_HOSPITAL = R.ID_HOSPITAL)
       JOIN ROLL_EVENT RE ON (R.ID_ROLL = RE.ID_ROLL)
       LEFT JOIN PGG P ON RE.KOD_PGG = P.CODE_PGG
       JOIN OKATO O ON (H.ID_OKATO = O.ID_OKATO)
       LEFT JOIN ROLL_DEFECT RD ON (RE.ID_ROLL_EVENT = RD.ID_ROLL_EVENT) AND (RD.ID_DEFECT = 60)
       LEFT JOIN ROLL_DEFECT_M RDM ON (RE.ID_ROLL_EVENT = RDM.ID_ROLL_EVENT) AND (RDM.D_SAVE <= :D_END)
 WHERE R.D_SAVE <= :D_END
   AND R.CODE_STATUS <> 0
 GROUP BY 1, 2, 3
в таком виде он не компилится с ошибкой:
SQL error code = -104.
Invalid expression in the select list (not contained in either an aggregate function or the GROUP BY clause).


Если в секции:

Код: Выделить всё

(SELECT SUM(PM.SUM_PAY)
          FROM PAYMENT PM JOIN HOSPITAL_CONTRACT HC ON (PM.ID_HOSPITAL_CONTRACT = HC.ID_HOSPITAL_CONTRACT)
         WHERE PM.ID_HOSPITAL = H.ID_HOSPITAL
           AND PM.D_DOCUMENT <= :D_END
           AND HC.CODE_TYPE = P.CODE_TYPE) AS SUM_PAYMENT
убрать AND HC.CODE_TYPE = P.CODE_TYPE, то запрос компилится, но результат не верен - оплата идет не в разрезе типа договора, а в разрезе ЛПУ... происходит задвоение оплаты.
Что то я сообразить не могу как это обойти...
Можно конечно через хроник переписать запрос, но не очень хочется это делать...

Добавлено: 27 сен 2006, 11:51
WildSery
А если написать не "(SELECT SUM(PM.SUM_PAY) FROM PAYMENT ...", а "SUM((SELECT SUM(PM.SUM_PAY) FROM PAYMENT ...", компилится?

Добавлено: 27 сен 2006, 12:12
Лысый
WildSery писал(а):А если написать не "(SELECT SUM(PM.SUM_PAY) FROM PAYMENT ...", а "SUM((SELECT SUM(PM.SUM_PAY) FROM PAYMENT ...", компилится?
Попробовал - нет.
Я так понимаю, что вся проблема в то что я пытаюсь для корелляции использовать P.CODE_TYPE, но тогда почему получилось внести H.ID_HOSPITAL, чем они отличаются?

Добавлено: 27 сен 2006, 12:44
Dimitry Sibiryakov
По H.ID_HOSPITAL группирвка есть, а по P.CODE_TYPE - нет. И это большая разница. Сервер не знает какой именно P.CODE_TYPE использовать.

Добавлено: 27 сен 2006, 12:51
Лысый
Dimitry Sibiryakov писал(а):По H.ID_HOSPITAL группирвка есть, а по P.CODE_TYPE - нет. И это большая разница. Сервер не знает какой именно P.CODE_TYPE использовать.
Совершенно точно! Уже сделал :) Всем спасибо.