Не ошибка выражения группы - PullRequest
1 голос
/ 05 апреля 2011

У меня есть SQL, как это;

SELECT B.MUS_K_ISIM AS CUSTOMER_NAME, B.HESAP_NO AS CUSTOMER_NO,
    SUM(B.RISK) AS TOTAL_RISK, 
    (CASE WHEN B.DOVIZ_KOD = 21 THEN 'EUR' WHEN B.DOVIZ_KOD = 2 THEN 'USD' WHEN B.DOVIZ_KOD = 1 THEN 'TL' END) AS CCY,
    ROUND(RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD),2) AS TOTAL_RISK_EUR,
    ROUND(SUM(MV_EX(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR)),2) AS RESALE_VALUE_OLD,
    ROUND(SUM(M_V(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR)),2) AS RESALE_VALUE_NEW,
    NVL(IPOTEK(B.HESAP_NO),0) AS SECURITIES,
    NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 0, 30, B.DOVIZ_KOD),2),0) AS BUCKET1,
    NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 30, 60, B.DOVIZ_KOD),2),0) AS BUCKET2,
    NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 60, 90, B.DOVIZ_KOD),2),0) AS BUCKET3,
    NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD),2),0) AS BUCKET4,
    (CASE WHEN GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD) > 0 THEN 100 WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 100 ELSE 0 END) AS PROV,
    (CASE WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 'E' ELSE 'H' END) AS CAT5,
    ROUND(RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD)-SUM(M_V(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR))-NVL(IPOTEK(B.HESAP_NO),0),2) AS NET_PROV,
    (CASE WHEN (RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD)-SUM(M_V(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR))-NVL(IPOTEK(B.HESAP_NO),0))<0 OR 
    NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD),2),0) <= 0 THEN 0 
    ELSE ROUND((RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD)-SUM(M_V(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR))-NVL(IPOTEK(B.HESAP_NO),0)),2) END) AS CORR_PROV
    FROM S_TEKLIF B
    WHERE NVL(B.RISK,0) > 0 
    --AND (GECIKME_CV(:TAR,B.HESAP_NO, 60, 90, B.DOVIZ_KOD) > 0 OR GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD) > 0) 
    GROUP BY B.MUS_K_ISIM, B.HESAP_NO, (CASE WHEN B.DOVIZ_KOD = 21 THEN 'EUR' WHEN B.DOVIZ_KOD = 2 THEN 'USD' WHEN B.DOVIZ_KOD = 1 THEN 'TL' END), ROUND(RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD),2), NVL(IPOTEK(B.HESAP_NO),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 0, 30, B.DOVIZ_KOD),2),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 30, 60, B.DOVIZ_KOD),2),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 60, 90, B.DOVIZ_KOD),2),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD),2),0), (CASE WHEN GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD) > 0 THEN 100 WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 100 ELSE 0 END), (CASE WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 'E' ELSE 'H' END)
    ORDER BY B.MUS_K_ISIM

Но я получаю эту ошибку.

ORA-00979: not a GROUP BY expression
00979. 00000 -  "not a GROUP BY expression"
*Cause:    
*Action:

Я не могу поставить этот код на GROUP BY?

(CASE WHEN GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD) > 0 THEN 100 WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 100 ELSE 0 END)

Я не понимаю ошибку !!

Ответы [ 4 ]

2 голосов
/ 05 апреля 2011
 , ROUND ( RISK_CV ( :TAR , B.HESAP_NO , B.DOVIZ_KOD )
         - SUM ( M_V ( B.TEKLIF_NO1 , B.TEKLIF_NO2 , :TAR ) )
  - NVL ( IPOTEK ( B.HESAP_NO ) , 0 ) , 2 )         

Это не агрегатная функция. Только часть суммы здесь. Используйте Аналитические функции .

2 голосов
/ 05 апреля 2011

Действительно раздражает особенность стандарта ANSI SQL, что любой столбец, который не является агрегатом, должен быть включен в предложение GROUP BY.Это классическая часть глупого дублирования, когда это очевидно (я считаю, что MySQL позволяет нам игнорировать эту часть стандарта).

Итак, я боюсь, что это значит, вам нужно включить CASE() предложение в предложении GROUP BY.


Я думаю, проблема в том, что вы ссылаетесь на SUM() на двух уровнях в запросе: оба на самом верхнем уровне, SUM(B.RISK), но также и в вычислениях, которые предоставляют значения группировки:

( CASE WHEN ( RISK_CV ( :TAR , B.HESAP_NO , B.DOVIZ_KOD )
                   - SUM ( M_V ( B.TEKLIF_NO1 , B.TEKLIF_NO2 , :TAR ) )
                   - NVL ( IPOTEK ( B.HESAP_NO ) , 0 ) ) < 0

Это довольно сложно понять правильно.

Я думаю, что самый простой способ решить эту проблему - создать запрос из вложенных встроенных запросов.Я переписал ваш запрос с тремя уровнями.Самый внутренний запрос - IQ - выбирает данные, включая функции без каких-либо агрегатов.Средний запрос - SQ - подсчитывает суммы.Внешний запрос относится к округлению и прочим вещам;это должно вернуть результаты согласно вашему существующему запросу.

SELECT sq.MUS_K_ISIM AS CUSTOMER_NAME, 
    sq.HESAP_NO AS CUSTOMER_NO,
    sq.TOTAL_RISK,
    (CASE WHEN sq.DOVIZ_KOD = 21 THEN 'EUR' 
        WHEN sq.DOVIZ_KOD = 2 THEN 'USD' 
        WHEN sq.DOVIZ_KOD = 1 THEN 'TL' END) AS CCY,
    ROUND(sq.RISK_EUR,2) AS TOTAL_RISK_EUR,
    ROUND(sq.RESALE_VALUE_OLD,2) AS RESALE_VALUE_OLD,
    ROUND(sq.RESALE_VALUE_OLD,2) AS RESALE_VALUE_NEW,
    sq.SECURITIES,
    NVL(ROUND(sq.BUCKET1,2),0) AS BUCKET1,
    NVL(ROUND(sq.BUCKET2,2),0) AS BUCKET2,
    NVL(ROUND(sq.BUCKET3,2),0) AS BUCKET3,
    NVL(ROUND(sq.BUCKET4,2),0) AS BUCKET4,
    (CASE WHEN sq.BUCKET4,2) > 0 THEN 100 
            WHEN sq.CAT5 = 'H' THEN 100 
            ELSE 0 END) AS PROV,
    sq.CAT5,
    sq.NET_PROV,
    (CASE WHEN sq.NET_PROV <0 
    OR
    sq.RISK_EUR <= 0 THEN 0
    ELSE ROUND(sq.NET_PROV,2) END) AS CORR_PROV
from (
    select 
            iq.MUS_K_ISIM , 
            iq.HESAP_NO ,
            iq.DOVIZ_KOD, 
            iq.RISK_EUR,
            iq.SECURITIES,
            iq.BUCKET1,
            iq.BUCKET2,
            iq.BUCKET3,
            iq.BUCKET4,
            iq.CAT5
            sum(iq.RISK) as TOTAL_RISK,
            sum(iq.RESALE_VALUE_OLD) as RESALE_VALUE_OLD,
            sum(iq.RESALE_VALUE_NEW) as RESALE_VALUE_NEW,
            iq.RISK_EUR - sum(iq.RESALE_VALUE_NEW) - iq.SECURITIES) AS NET_PROV
        from (
            SELECT B.MUS_K_ISIM , 
                   B.HESAP_NO ,
                   B.RISK,
                   B.DOVIZ_KOD, 
                   RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD) AS RISK_EUR,
                   MV_EX(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR) AS RESALE_VALUE_OLD,
                   M_V(B.TEKLIF_NO1,B.TEKLIF_NO2,:TAR) AS RESALE_VALUE_NEW,
                   NVL(IPOTEK(B.HESAP_NO),0) AS SECURITIES,
                   GECIKME_CV(:TAR,B.HESAP_NO, 0, 30, B.DOVIZ_KOD) AS BUCKET1,
                   GECIKME_CV(:TAR,B.HESAP_NO, 30, 60, B.DOVIZ_KOD) AS BUCKET2,
                   GECIKME_CV(:TAR,B.HESAP_NO, 60, 90, B.DOVIZ_KOD) AS BUCKET3,
                   GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD) AS BUCKET4,
                   nvl2(M.HESAP_NO, 'E', 'H') AS CAT5
            from     
                FROM S_TEKLIF B
                    left outer join S_TAKIP_MUSTERI on (B.HESAP_NO = M.HESAP_NO)
                WHERE NVL(B.RISK,0) > 0
            ) iq        
        group by     
                iq.MUS_K_ISIM , 
                iq.HESAP_NO ,
                iq.DOVIZ_KOD, 
                iq.RISK_EUR,
                iq.SECURITIES,
                iq.BUCKET1,
                iq.BUCKET2,
                iq.BUCKET3,
                iq.BUCKET4,
                iq.CAT5
        )sq
ORDER BY sq.MUS_K_ISIM
/

Очевидно, что это может не скомпилироваться - у меня нет схемы вашей базы данных для проверки.Также логика может быть неправильной;Я должен был сделать предположения о вашей бизнес-логике.Тем не менее, я думаю, что это легче понять и легче будет отладить.

1 голос
/ 05 апреля 2011

Прежде всего, вы можете опубликовать полный пример в следующий раз - при попытке выполнить запрос я получаю ошибки как минимум для 4 неопределенных функций и 2 несуществующих таблиц (S_TEKLIF, GECIKME_CV, ipotek, risk_cv, m_v,mv_ex - я сдался после этого).

Второе: попробуйте разделить это на два запроса, что-то вроде

select mus_k_isim, hesap_no, my_key, ... from 
(select mus_k_isim, b.hesap_no, 
  (CASE WHEN B.DOVIZ_KOD = 21 THEN 'EUR' WHEN B.DOVIZ_KOD = 2 THEN 'USD' WHEN B.DOVIZ_KOD = 1 THEN 'TL' END), ROUND(RISK_CV(:TAR,B.HESAP_NO,B.DOVIZ_KOD),2), NVL(IPOTEK(B.HESAP_NO),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 0, 30, B.DOVIZ_KOD),2),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 30, 60, B.DOVIZ_KOD),2),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 60, 90, B.DOVIZ_KOD),2),0), NVL(ROUND(GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD),2),0), (CASE WHEN GECIKME_CV(:TAR,B.HESAP_NO, 90, 9999, B.DOVIZ_KOD) > 0 THEN 100 WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 100 ELSE 0 END), (CASE WHEN B.HESAP_NO IN (SELECT HESAP_NO FROM S_TAKIP_MUSTERI) THEN 'E' ELSE 'H' END) my_key
from ...
) group by mus_k_isim, hesap_no, my_key
0 голосов
/ 05 апреля 2011

Ваш case ссылается на оператор выбора - и вы не можете иметь оператор выбора в предложении group by.

...