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
juris
post
Post #2





Grupa: Zarejestrowani
Postów: 8
Pomógł: 1
Dołączył: 12.03.2014

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


Nie ma co gdybać co jest bardzie a co mniej wydajne - najlepiej to po porstu sprawdzić.

Zarówno zaproponowane przez kolegę podzapytanie skorelowane :
  1. SELECT Nazwisko
  2. FROM dbo.Pracownicy AS T1
  3. WHERE Placa_Pod =
  4. (
  5. SELECT MIN(Placa_Pod) AS Low
  6. FROM dbo.Pracownicy
  7. WHERE (Etat = T1.Etat)
  8. )

Jak i dwa inne rozwiązania (moim zdaniem całkiem eleganckie (IMG:style_emoticons/default/smile.gif) ) dadzą takie same EFEKTY jeśli chodzi o wydajność. W końcu CROSS APPLY to nic innego jak zapytanie skorelowane.... a CTE (IMG:style_emoticons/default/questionmark.gif) ? hmmm w tym przypadku chyba tylko żeby poprawić czytelność. Warto poczytać porównania wydajnościowe, dla podzapytań skorelowanych na www.sqlpedia.pl - również dot. CTE, grupowania czy joinów.
  1. SELECT T1.Nazwisko
  2. FROM dbo.Pracownicy T1 CROSS APPLY
  3. (
  4. SELECT MIN(Placa_Pod) AS Low
  5. FROM dbo.Pracownicy
  6. WHERE (Etat = T1.Etat)
  7. ) a
  8. WHERE Placa_pod = Low
  9.  
  10. SELECT T1.Nazwisko
  11. FROM dbo.Pracownicy T1 INNER JOIN
  12. (
  13. SELECT Etat,MIN(Placa_Pod) AS Low
  14. FROM dbo.Pracownicy
  15. GROUP BY Etat
  16. ) m ON T1.Etat = m.Etat AND T1.Placa_Pod = m.Low

Każda z tych kwerend da identyczny plan wykonania. BTW - warto dodać jeszcze indeks np. taki :
  1. CREATE nonclustered INDEX Placa_pod_inc_Nazwisko ON dbo.Pracownicy(Etat,Placa_Pod) include ( Nazwisko )


Który dramatycznie poprawi wydajność (IMG:style_emoticons/default/smile.gif)

pozrdrowienia !

Ten post edytował juris 12.03.2014, 09:17:16
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: 7.10.2025 - 18:00