Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> (Nie)Eleganckie zapytanie tablicowe., Prośba o pomoc w sformułowaniu zapytania…
Morfina
post
Post #1





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 4.09.2013

Ostrzeżenie: (0%)
-----


Witam,
Mam problem w odpytaniu Bazy danych w sposób „elegancki”, już tłumaczę o co chodzi.
Dane:
(IMG:http://imageshack.com/a/img827/9602/ncvm.jpg)

Zadanie:
Wyszukaj pracowników zarabiających najmniej na danym etacie.

Rozwiązanie, którego bym oczekiwał i uważam za eleganckie powinno mieć postać:

SELECT nazwisko FROM pracownicy
WHERE ( Etat , Placa_pod ) IN (SELECT Etat, MIN(Placa_pod) FROM pracownicy GROUP BY etat);

Niestety nie działa ono na MS SQL.

Rozwiązanie, które działa ale jest wg. mnie gorsze (nieeleganckie) ma postać:

SELECT dbo.Pracownicy.Nazwisko, dbo.Pracownicy.Imie
FROM dbo.Pracownicy INNER JOIN
(SELECT MIN(Placa_Pod) AS Min, Etat
FROM dbo.Pracownicy AS Pracownicy_1
GROUP BY Etat) AS P_1 ON dbo.Pracownicy.Placa_Pod = P_1.Min AND dbo.Pracownicy.Etat = P_1.Etat

Czy któryś z szanownych forumowiczów ma pomysł na rozwiązanie bez użycia JOIN ?

Z góry dziękuję Morf.



Witam ponownie,
po nocnych przemyśleniach:

SELECT Nazwisko, Imie
FROM dbo.Pracownicy AS T1
WHERE (Placa_Pod =
(SELECT MIN(Placa_Pod) AS Low
FROM dbo.Pracownicy
WHERE (Etat = T1.Etat)))

Poziom elegancji 7 / 10 i dodatkowy punkcik za bark JOIN czyli 8 /10 :-)

w zasadzie jest OK chyba, że...

Pozdrawiam Morf




Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
Morfina
post
Post #2





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 4.09.2013

Ostrzeżenie: (0%)
-----


Cytat(pmir13 @ 4.03.2014, 15:14:03 ) *
Po raz pierwszy słyszę by ktoś uznawał rozwiązanie z JOIN za mało eleganckie, a rozwiązanie z IN() za bardziej eleganckie. Bazy danych niezależnie od silnika mają metody optymalizacji JOINów tak wyśrubowane, że przy prawidłowym wykorzystaniu indeksów złączenia są najbardziej wydajnymi rozwiązaniami. W zasadzie podane "nieeleganckie rozwiązanie" jest klasyką jeśli chodzi o problemy typu szukanie minimum/maximum w grupach i działa poprawnie praktycznie we wszystkich dialektach SQL. Wprawdzie istnieją szybsze metody, ale są one dostosowane do konkretnego silnika, na przykład dla MSSQL byłoby to rozwiązanie oparte na CTE i CROSS APPLY. Ciekawi mnie czym kieruje się autor wątku oceniając elegancję, bo z pewnością nie jest to wydajność, a i czytelność też raczej nie, bo widząc GROUP BY w podzapytaniu i JOIN do całej tabeli by pobrać resztę kolumn większość ludzi z jakimś doświadczeniem w SQL jest w stanie natychmiast stwierdzić co dokładnie takie zapytanie ma robić.


Witam ponownie,

Udało mi się przetestować oba rozwiązania:

Zapytanie:
SELECT Imię, Nazwisko, Zespół, Płaca
FROM Testowa_1 AS T1
WHERE Płaca =
(SELECT MAX(Płaca)
FROM Testowa_1 AS T2
WHERE Zespół = T1.Zespół)

Jest o około 10 % szybsze od zapytania:

SELECT T1.Imię, T1.Nazwisko, T1.Zespół, T1.Płaca
FROM dbo.Testowa_1 AS T1 INNER JOIN
(SELECT Zespół, MAX(Płaca) AS Exp1
FROM dbo.Testowa_1
GROUP BY Zespół) AS T2 ON T1.Zespół = T2.Zespół AND T1.Płaca = T2.Exp1;

Testowałem na MS SQL 2008 R2
Tak więc kolega pmir13 chyba nie ma jednak do końca racji...
Jedno zwraca wynik po około 78s a drugie 86s (średnia 10 odpytań).

Pozdrawiam Morf

Go to the top of the page
+Quote Post

Posty w temacie


Reply to this topicStart new topic
2 Użytkowników czyta ten temat (2 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Aktualny czas: 8.10.2025 - 19:18