Krzysztof Durołek

Krzysztof Durołek lead developer,

Temat: Zagwozdka MySQL.

Witam,

mam pewien problem ze skonstruowanie prawidłowego zapytania SQL. Oto problem. Baza zawiera takie dane:

ROUTE | SYSTEM | AMOUNT
---------------------------
WAW-POZ | S1 | 10
WAW-POZ | S2 | 20
GDA-WAW | S2 | 50
GDA-WAW | S1 | 100

Interesuje mnie informacja króry system miał na danej trasie większą wartość AMOUNT. Czyli prawidłowym wynikiem byłoby

WAW-POZ | S2 | 20
GDA-WAW | S1 | 100

Struktura jest dokładnie jak opisałem i nie ma możliwości jej zmiany. Jest efektem działania innych zapytań SQL (podzapytań).
GROUP BY nie zdaje egzaminu ponieważ pokazuje pierwszy z listy, DISTICT też nie działa. ???

Bardzo proszę o pomoc. Spędziłem wiele czasu na poszukiwaniu rozwiązania w necie. Znalazłem również podobne posty, jednak w żadnym nikt nie podał działającego rozwiązania.

Pozdrawiam i z góry dziękuję za pomoc
Pawel M.

Pawel M. oracle, middleware,
jboss, apache

Temat: Zagwozdka MySQL.

select t.route,t.systems,t.amount
from test t where t.amount = (select max(amount) from test i where i.route = t.route)

O to chodzilo?
Michał Jarosz

Michał Jarosz Frontend Developer &
Team Leader

Temat: Zagwozdka MySQL.

I od razu przesuwamy podzapytanie z WHERE do JOINa


SELECT
t.route, t.system, t.amount
FROM
test AS t
CROSS JOIN (
SELECT
route,
MAX(amount) AS amount
FROM
test
GROUP BY
route
) AS t1
USING (route, amount)
Krzysztof Durołek

Krzysztof Durołek lead developer,

Temat: Zagwozdka MySQL.

Dziękuję za pomoc. Oba zapytania działają i w 100% o to mi chodziło. Jakoś nie mogłem uchwycić tego rozwiązania i sporo czasu spędziłem na testach.

Pozdrawiam
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: Zagwozdka MySQL.

U mnie zadziałało to:

SELECT test.* FROM test GROUP BY route HAVING amount=max(amount)

KISS

konto usunięte

Temat: Zagwozdka MySQL.

a ja polecam z joinami bo jest teoretycznie najszybciej:
pod spodem mój artykuł na ten temat
http://tworzenie-web.pl/2010/02/16/grupowanie-po-klucz...

chodzi o zjoinowanie tabeli samej ze sobą i dodanie warunku do łącząc route a potem warunek dodatkowy joina
np dla aliasów t1 i t2 t1.amount < t2.amount . wtedy w wherze jak damy warunek t2.route is null wtedy wybiera nam tylko tą krotkę która jest faktycznie największa.
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: Zagwozdka MySQL.

Sprytna sztuczka z left joinem ale ciekawe ile naprawdę szybsza od innych rozwiązań. Czy jest to 10-30% czy np. 300% lub więcej?
Michał Jarosz

Michał Jarosz Frontend Developer &
Team Leader

Temat: Zagwozdka MySQL.

Wojciech Sobala:
U mnie zadziałało to:

SELECT test.* FROM test GROUP BY route HAVING amount=max(amount)

KISS

A zwróciło jakieś wiersze?
Pawel M.

Pawel M. oracle, middleware,
jboss, apache

Temat: Zagwozdka MySQL.

Michał Jarosz:
Wojciech Sobala:
U mnie zadziałało to:

SELECT test.* FROM test GROUP BY route HAVING amount=max(amount)

KISS

A zwróciło jakieś wiersze?

Coś nie bardzo bangla to zapytanie..Pawel M. edytował(a) ten post dnia 18.02.10 o godzinie 16:49
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: Zagwozdka MySQL.

Michał Jarosz:
Wojciech Sobala:
U mnie zadziałało to:

SELECT test.* FROM test GROUP BY route HAVING amount=max(amount)

KISS

A zwróciło jakieś wiersze?

Zwróciło w SQLite

Oto cytat ze strony SQLite:
"The GROUP BY clause causes one or more rows of the result to be combined into a single row of output. This is especially useful when the result contains aggregate functions. The expressions in the GROUP BY clause do not have to be expressions that appear in the result. The HAVING clause is similar to WHERE except that HAVING applies after grouping has occurred. The HAVING expression may refer to values, even aggregate functions, that are not in the result."

Najważniejsze jest ostatnie sformułowanie.Wojciech Sobala edytował(a) ten post dnia 18.02.10 o godzinie 20:39

konto usunięte

Temat: Zagwozdka MySQL.

Wojciech Sobala:
U mnie zadziałało to:

SELECT test.* FROM test GROUP BY route HAVING amount=max(amount)

KISS

korzystałem ostatnio z Twojego rozwiązania i muszę powiedzieć że to rozwiązanie nie działa do końca poprawnie. W zestawieniu z pewnymi tabelami zjoinowanymi odrzucało mi bez konkretnego powodu wyniki które normalnie powinny się pojawić. Więc musiałem wykombinować to rozwiązanie które zaproponowałem wcześniej z joinami. Tak więc nie jestem do końca przekonany co do tego rozwiązania.
Michał Jarosz

Michał Jarosz Frontend Developer &
Team Leader

Temat: Zagwozdka MySQL.

Wojciech Sobala:
Najważniejsze jest ostatnie sformułowanie.Wojciech Sobala edytował(a) ten post dnia 18.02.10 o godzinie 20:39

Co by tam nie było napisane, SQLite != MySQL. Dla podanych w pierwszym poście danych MySQL nie zwraca żadnych wierszy.
Wojciech Sobala

Wojciech Sobala Redaktor
statystyczny,
biostatystyk,
Instytut Medycyny
Pr...

Temat: Zagwozdka MySQL.

Z ciekawości zajrzałem do ANSI SQL-92. I pozornie zapytanie z having powinno być równoważne Select z Select .. Group By, ale czytając fragment odnośnie implementacji to moje rozwiązanie ma też prawo działać o ile implementacja jest zgodna z ANSI SQL-92.

Niemniej jednak całe zamieszanie wynika z tego, że odwołanie do konkretnej bazy było w temacie a nie w treści, a ja tą informację zignorowałem.

Następna dyskusja:

Zapytanie MySQL




Wyślij zaproszenie do