MSSQL - Group By i Max, co z pozostałymi polami?

0

Witam,

Posiadam takie dane


ALT_KEY_HIST    DATA    ID_TOWARU
E759B73E-7134-4E15-A7A9-617C168EF655    2011-07-07 10:58:17.957 004623
37208C0C-14CD-4B5C-A71D-7329E0677D41    2011-08-26 17:02:58.350 004623
232DC61A-509B-4078-9210-7491077404DB    2011-07-29 07:40:17.713 004623
D1E799E8-5249-4A3B-8BBA-C12201294B97    2011-07-13 11:54:40.150 004623
5FD9332B-94A3-4ADD-8336-C8956E8D6694    2011-07-07 10:58:17.953 004623
F20142ED-5FE2-4C9D-8A1D-D200623397E3    2011-07-13 11:54:40.153 004623
49DAFBAC-F920-404B-99AE-D980445D755A    2011-08-26 18:02:22.297 004623
D759B73E-7134-4E15-A7A9-617C168EF655    2012-07-07 10:58:17.957 004624
27208C0C-14CD-4B5C-A71D-7329E0677D41    2012-08-26 17:02:58.350 004624
132DC61A-509B-4078-9210-7491077404DB    2012-07-29 07:40:17.713 004624
C1E799E8-5249-4A3B-8BBA-C12201294B97    2012-07-13 11:54:40.150 004624
4FD9332B-94A3-4ADD-8336-C8956E8D6694    2012-07-07 10:58:17.953 004624
E20142ED-5FE2-4C9D-8A1D-D200623397E3    2012-07-13 11:54:40.153 004624
39DAFBAC-F920-404B-99AE-D980445D755A    2012-08-26 18:02:22.297 004624

Chciałbym wybrać stąd:

ALT_KEY_HIST    DATA    ID_TOWARU
49DAFBAC-F920-404B-99AE-D980445D755A    2011-08-26 18:02:22.297 004623
39DAFBAC-F920-404B-99AE-D980445D755A    2012-08-26 18:02:22.297 004624

Jak powinno wyglądać zapytanie?

SELECT ALT_KEY_HIST, max (DATA), ID_TOWARU FROM tabela group by ID_TOWARU 

Co nałożyć na ALT_KEY_HIST? Bo w tym wypadku jest

Msg 8120, Level 16, State 1, Line 1
Column 'qin.ALT_KEY_HIST' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
0
SELECT ALT_KEY_HIST, MAX (DATA), ID_TOWARU FROM tabela GROUP BY ID_TOWARU, ALT_KEY_HIST;
0

AdamPL mylisz się.
Wtedy wyświetla wszystkie rekrody, bo co z tego, że ID_TOWARU jest to samo i zakładasz GroupBy, ale przecież ALT_KEY_HIST są różne.
Wyświetla wszystkie rekordy.

Musi być jakieś inne rozwiązanie i z tego co widzę, nie będzie łatwe.

0

Jeszcze się z tym męczysz??

SELECT m.* FROM tabela m JOIN (SELECT id_towaru, Max(data) data FROM tabela GROUP BY id_towaru) X ON x.id_towru=m.id_towaru AND x.data=m.data

pozdrawiaMM

0

Max lub Min. Lub zapytanie skorelowane, lub całość z podzapytaniem :)

Max lub min nie może być bo to nie liczba.
Całość z podzapytaniem, oraz zapytaniem skorelowanym nie może być, bo wybrane dane nie pochodzą z jednej tabeli tylko jest to UNION z dwóch różnych tabel.

0
Marcin.Miga napisał(a)

Jeszcze się z tym męczysz??

SELECT m.* FROM tabela m JOIN (SELECT id_towaru, Max(data) data FROM tabela GROUP BY id_towaru) X ON x.id_towru=m.id_towaru AND x.data=m.data

pozdrawiaMM

No właśnie to jest podzapytanie, a ja w środku zamiast

SELECT id_towaru, Max(data) data FROM tabela GROUP BY id_towaru

mam coś jakby

SELECT id_towaru, Max(data) data FROM tabela GROUP BY id_towaru UNION SELECT id_towaru, Max(data) data FROM tabela2 GROUP BY id_towaru

Wtedy jak odnieść podzapytanie?

Problem rozwiązałem po stronie PHP, ale przeglądając kod pod kątem optymalizacji/czyszczenia to mało nie zwymiotowałem, przecież musi być sposób, żeby zrobić to od strony bazy.

0

Nie podałeś konkretnie po jakim kryterium te dane mają być wyciągane ?

Domyślam się, że mają być rekordy z maksymalną datą dla danego id_towaru.

Jeśli tak, to kwerenda mogłaby wyglądać np. tak:

select *
from tabela
where (id_towaru, data ) IN (
select id_towaru, max(data)
from tabela
group by id_towaru
)

Jeśli ma to być po innym kryterium, to podaj proszę jakie to konkretnie kryterium.

Co do optymalizacji takiego zapytania .... to już temat na inną opowieść.

0

Mam dwa SELECTy połączone UNION. Z nich chce wyciągnąć ID_TOWARU i kilka innych pól dla maksymalnej daty.
Z ID_TOWARU jest spokój, bo robimy group by ID_TOWARU. Z datą jest spokój bo jest max(DATA), a co np. z CENA_SPRZEDAZY, CENA_ZAKUPU, dla max(DATA).

0

MAX chcesz wyciągać przed zrobieniem union, czy po?

SELECT id_towaru, MAX(DATA) DATA FROM tabela GROUP BY id_towaru UNION SELECT id_towaru, MAX(DATA) DATA FROM tabela2 GROUP BY id_towaru

czy

SELECT id_towaru, MAX(DATA) FROM (SELECT id_towaru, DATA FROM tabela UNION SELECT id_towaru, DATA FROM tabela2) t GROUP BY id_towaru

?

Te dwa zapytania mogą zwrócić różne wyniki.
Jeżeli towar jest w obydwu tabelach, to pierwsze zapytanie zwróci dwa wyniki (po jednym z każdej tabeli), a drugie jeden wynik - max z obydwu tabel.

Jeżeli chodzi o drugą sytuację, to proponuję, jako rozwiązanie (nie trzeba używać group by!):

SELECT t.ALT_KEY_HIST, t.id_towaru, t.DATA
FROM (SELECT ALT_KEY_HIST, id_towaru, DATA FROM tabela UNION SELECT ALT_KEY_HIST, id_towaru, DATA FROM tabela2) t
LEFT JOIN (SELECT ALT_KEY_HIST, id_towaru, DATA FROM tabela UNION SELECT ALT_KEY_HIST, id_towaru, DATA FROM tabela2) t2 
ON t.DATA < t2.DATA AND t.id_towaru = t2.id_towaru
WHERE t2.id_towaru IS NULL

Zapytanie pobiera z tabeli t tylko te rekordy, dla których nie istnieje rekord ("t2.id_towaru IS NULL") z tym samym id_towaru oraz większym DATA ("LEFT JOIN ... ON t.DATA < t2.DATA AND t.id_towaru = t2.id_towaru").

Polecam zrobienie widoku z tymi dwoma tabelami. Wtedy zapytanie się bardzo uprości:

SELECT t.ALT_KEY_HIST, t.id_towaru, t.DATA
FROM widok t
LEFT JOIN widok t2
ON t.DATA < t2.DATA AND t.id_towaru = t2.id_towaru
WHERE t2.id_towaru IS NULL

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