podzapytanie sql

0

Cześć,

Mam niestety problem ze zrozumieniem przebiegu poniższego zapytania. W jaki sposób "działa" pogrubiona część ?

Zapytanie pokazuje trzech najlepiej zarabiających pracowników.

select nazwisko,zarobki
from ludzie l
where 3>(select count(*)
from ludzie
where l.zarobki<zarobki)

Może jest banalne, ale niestety nie dla mnie :(
Z góry dzięki za pomoc

0

L.zarobki jest z pierwszego FROMa. Masz tam from ludzie L, więc możesz się do kolumn z tej tabelki odwoływać z L na początku. Drugie zarobki są z selecta w where. Czyli sprawdzasz czy zarobki z pierwszego froma są mniejsze od tego z where. Chaotycznie opisałem, późno już :)

0

Po pierwsze jak wklejasz kod na forum, to wstawiaj go w znaczniki formatujące składnie:

SELECT nazwisko, zarobki
FROM ludzie l
WHERE 3 > (SELECT Count(*)
  FROM ludzie
  WHERE l.zarobki < zarobki)
3

Zadaj sobie pytanie co to zapytanie zwraca. A zwraca listę nazwisk i zarobków z tabeli ludzie, filtrując tylko tych dla których istnieją przynajmniej 4 rekordy o większych zarobkach.
Wiec do from rozumiesz, tu ważny jest nadany alias l dla tabeli ludzie. Warunek where sprawdza ilość rekordów dla zarobków większych od tych w filtrowanym wierszu tu kluczowy jest warunek podzapytania l.zarobki < zarobki l.zarobki wskazuje na wartość z wiersza filtrowanego, zarobki odwołuje się do tabeli z podzapytania.
Aby to zrozumieć to zrób tak:

SELECT 
   nazwisko
  , zarobki
 ,(SELECT COUNT(*)  FROM ludzie  WHERE l.zarobki < zarobki) IleOsobZarabieWiecej
FROM
   ludzie l

I zapis twojego zapytania:

select nazwisko,zarobki
from (
      SELECT 
         nazwisko
        , zarobki
       ,(SELECT COUNT(*)  FROM ludzie  WHERE l.zarobki < zarobki) IleOsobZarabieWiecej
   FROM
      ludzie l
) dt
where IleOsobZarabieWiecej>3

Napomknę tylko że taki sposób, jest zabójczy, bo dla każdego rekordu w warunku where wykonasz podzapytanie, w uproszczeniu tyle razy zapytasz bazę o ilość ile rekordów ma tabela ludzie.
Bardziej by pasował taki zapis (celowo dodaje id, zakładając, że takie pole istnieje w tabeli ludzie, ponieważ może się zdarzyć, że nazwisko będzie powielone)

SELECT
   l.id
  ,l.nazwisko
  ,l.zarobki
FROM
   ludzie l
   inner join ludzie iw on l.zarobki < iw.zarobki
group by
   l.id
  ,l.nazwisko
  ,l.zarobki
having
  count(*) > 3
0

dzięki wielkie za wyjaśnienie .

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