błąd klauzuli group by/order by?

0

Witam. W IB Expert napisałem taki zapytanie:

SELECT  URLO_IDKADR, URLO_ID, URLO_DATAZAL, URLO_ROK, URLO_RODZAJ, URLO_DNINOM, URLO_IDWYMIARETATU, URLO_DNIRZECZ, max(URLO_IDETATU)
FROM KD_URLOPYWYP
WHERE URLO_IDKADR = 681 or URLO_IDKADR = 20 or URLO_IDKADR = 355 or URLO_IDKADR = 567 or URLO_IDKADR = 254 or URLO_IDKADR = 664 or URLO_IDKADR = 837
group BY URLO_IDKADR, URLO_ID, URLO_DATAZAL, URLO_ROK, URLO_RODZAJ, URLO_DNINOM, URLO_IDWYMIARETATU, URLO_DNIRZECZ
order BY URLO_IDETATU;

Jednak zapytanie nie działa i wyrzuca mi taki błąd:

SQL error code = -104.
Invalid expression in the ORDER BY clause (not contained in either an aggregate function or the GROUP BY clause)

W klauzuli group by mają być powtórzone te same kolumny, co w select poza funkcjami agregującymi. I to jest prawda.
W kolumnie gdzie jest max, to później jest wyciągnięte order by. Nie wiem w czym jest problem. Z góry dzięki za info.

1

nie możesz sortować po polu, które nie jest w group by.

0
abrakadaber napisał(a):

nie możesz sortować po polu, które nie jest w group by.

nie mogę sortować po polu, które nie jest w group by oraz nie mogę sortować po polu agregowalnym.
To może zadam inaczej pytanie:
chodzi o wwyciągnięcie takiego zapytania, które zwróci dla podanych wartości URLO_IDKADR maksymalną dla nich wartość etatu (URLO_IDETATU). Jednocześnie muszą być pokazane wszystkie pozostałe kolumny z tego selecta.
Przykładowo ma podać wartości jak na screenie.
Dla nr id 355 (ta lewa kolumna) powinien zwrócić wartość 933 (ta druga kolumna)
Dla nr id 567 powinienn zwrócić wartość 900.

screenshot-20200210150635.png

0

najpierw wyciągasz tylko te kolumny, które są unikalne i jednoznacznie identyfikują rekord a potem doklejasz resztę. Tu może to wyglądać tak

select * from tabela where (idkadr, idetatu) in (select idkadr, max(idetatu) from tabela group by idetatu)

Jeśli jednak para idkadr, max(idetatu) nie jest unikalna to musisz dorzucić kolejne pola, które tą unikalność zapewnią

0

dopisałem URLO_ROK do tego zapytania i teraz to wygląda tak:

select * from
kd_urlopywyp
where (URLO_IDKADR, URLO_IDETATU) in
select URLO_IDKADR, max(URLO_IDETATU), URLO_ROK
from kd_urlopywyp
group by URLO_IDETATU;

ale wywala mi taki błąd

can't format message 13:896 -- message file C:\WINDOWS\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 19.

0

subselect musi być w nawiasie

0
abrakadaber napisał(a):

subselect musi być w nawiasie
jest w nawiasie:

select * from
kd_urlopywyp
where (URLO_IDKADR, URLO_IDETATU) in
(select URLO_IDKADR, max(URLO_IDETATU), URLO_ROK
from kd_urlopywyp
group by URLO_IDETATU);

i nadal jest to samo:

can't format message 13:896 -- message file C:\WINDOWS\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 19.
,.

0

Nie możesz jednocześnie agregować i grupować po danej kolumnie. (URLO_IDETATU)
Po drugie w subselect masz trzy kolumny, a porównujesz je do dwóch wartości - tak się nie da...

0
Marcin.Miga napisał(a):

Nie możesz jednocześnie agregować i grupować po danej kolumnie. (URLO_IDETATU)
Po drugie w subselect masz trzy kolumny, a porównujesz je do dwóch wartości - tak się nie da...

Ok więc zastosowałem się do twoich wskazówek, czyli teraz mam to tak:

'select * from
kd_urlopywyp
where (URLO_IDKADR, URLO_IDETATU) in
(select URLO_IDKADR, max(URLO_IDETATU)
from kd_urlopywyp
group by URLO_IDKADR);'

jednak nadal jest ten sam błąd:
can't format message 13:896 -- message file C:\WINDOWS\firebird.msg not found.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 3, column 19.

Linia 3, kolumna 19-to chodzi o ten pierwszy przecinek w całym zapytaniu (po klauzuli where). Przy czym jeśli usunę ten przecinek, to komunikat jest taki sam. Coś jest chyba ze składnią tego zapytania, że system nie pozwala tutaj użyć kilku kolumn po klauzuli where.
,.

1

Spróbuj tak:

select 
  *
from
   kd_urlopywyp
where 
  (URLO_IDKADR, URLO_IDETATU) in
  ((select URLO_IDKADR, max(URLO_IDETATU) from kd_urlopywyp group by URLO_IDKADR));

lub tak:

select 
  *
from
   kd_urlopywyp u
   JOIN 
   (select URLO_IDKADR, max(URLO_IDETATU) URLO_IDETATU from kd_urlopywyp group by URLO_IDKADR) s
   on
  u.URLO_IDKADR=s.URLO_IDKADR AND  u.URLO_IDETATU=s.URLO_IDETATU;
0
Marcin.Miga napisał(a):

Spróbuj tak:

select 
  *
from
   kd_urlopywyp
where 
  (URLO_IDKADR, URLO_IDETATU) in
  ((select URLO_IDKADR, max(URLO_IDETATU) from kd_urlopywyp group by URLO_IDKADR));

lub tak:

select 
  *
from
   kd_urlopywyp u
   JOIN 
   (select URLO_IDKADR, max(URLO_IDETATU) URLO_IDETATU from kd_urlopywyp group by URLO_IDKADR) s
   on
  u.URLO_IDKADR=s.URLO_IDKADR AND  u.URLO_IDETATU=s.URLO_IDETATU;

Ten drugi wariant zadziałał. Dzięki za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1