Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Dlaczego powtarzają się rekordy?
Forum PHP.pl > Forum > Bazy danych > MySQL
Max Damage
Cześć, zrobiłem sobie zapytanie które wybiera mi wszystkie dane o najwyższej osobie w danym dziale:
  1. SELECT * FROM osoby JOIN (SELECT MAX(wzrost) AS max FROM osoby o JOIN dzialy d ON o.iddzialu = d.iddzialu GROUP BY d.iddzialu) AS aaa ON osoby.wzrost = aaa.max;
  2. +---------+----------+----------+---------+----------+--------+------+
  3. | IdOsoby | IdDzialu | Nazwisko | Imie | RokUrodz | wzrost | max |
  4. +---------+----------+----------+---------+----------+--------+------+
  5. | 6 | 4 | Nowicki | Jan | 1972 | 1.93 | 1.93 |
  6. | 6 | 4 | Nowicki | Jan | 1972 | 1.93 | 1.93 |
  7. | 9 | 1 | Zi?ba | Andrzej | 1972 | 1.69 | 1.69 |
  8. | 12 | 2 | Kowalski | Adam | 1980 | 1.76 | 1.76 |
  9. | 14 | 3 | Nowak | Edward | 1960 | 1.93 | 1.93 |
  10. | 14 | 3 | Nowak | Edward | 1960 | 1.93 | 1.93 |
  11. +---------+----------+----------+---------+----------+--------+------+

I teraz pytanie dlaczego dwa rekordy mi się powtarzają?
Dodam, że podzapytanie zwraca mi:
  1. +------+
  2. | max |
  3. +------+
  4. | 1.69 |
  5. | 1.76 |
  6. | 1.93 |
  7. | 1.93 |
  8. +------+

A w tabeli osoby mam powtarzające się wartości wzrost:
  1. +---------+----------+----------+--------+----------+--------+
  2. | IdOsoby | IdDzialu | Nazwisko | Imie | RokUrodz | wzrost |
  3. +---------+----------+----------+--------+----------+--------+
  4. | 6 | 4 | Nowicki | Jan | 1972 | 1.93 |
  5. | 14 | 3 | Nowak | Edward | 1960 | 1.93 |
  6. | 2 | 2 | Nowak | Karol | 1979 | 1.72 |
  7. | 3 | 3 | Kow | Piotr | 1967 | 1.72 |
  8. +---------+----------+----------+--------+----------+--------+

Wiem, że mogę sobie zrobić grupowanie i bedzie po problemie. Pytam jednak z czystej ciekawości.
Mchl
Bo raz JOIN łączy ci Nowaka ze wzrostem Nowaka a drugi raz ze wzrostem Nowickiego. Potem dla Nowickiego to samo.

Kod
SELECT
  *
FROM
  osoby
INNER JOIN (
  SELECT
    d.iddzialu AS iddzialu,
    MAX(wzrost) AS max
  FROM
    osoby o
  INNER JOIN
    dzialy d
  ON
    o.iddzialu = d.iddzialu
  GROUP BY d.iddzialu) AS aaa
ON
  osoby.wzrost = aaa.max AND osoby.IdDzialu = aaa.iddzialu
Max Damage
Faktycznie nie przyszło mi to do głowy, jeszcze jedno pytanie: gdybym wybrał w podzapytaniu idosoby i dopisał do swojego zapytania na końcu:
  1. WHERE osoby.idosoby != aaa.idosoby;

Dlaczego źle zadziała? Kasuje wtedy Nowickiego, ale Nowak nadal zostaje.
Mchl
Nie ma aaa.idosoby ani w mojej wersji, ani w Twojej.
Max Damage
Wiem, chodzi mi o sytualcje gdyby tam było:
  1. SELECT * FROM osoby INNER JOIN (
  2. SELECT MAX(wzrost) AS max,idosoby
  3. FROM osoby o
  4. INNER JOIN dzialy d
  5. ON o.iddzialu = d.iddzialu
  6. GROUP BY d.iddzialu
  7. ) AS aaa
  8. ON osoby.wzrost = aaa.max
  9. WHERE osoby.idosoby != aaa.idosoby;
Mchl
Podzapytanie
Kod
SELECT MAX(wzrost) AS max,idosoby
       FROM osoby o
       INNER JOIN dzialy d
       ON o.iddzialu = d.iddzialu
       GROUP BY d.iddzialu


Zawiera kolumnę nieagregowaną (idosoby) i nie występującą w klauzuli GROUP BY. Nie ma gwaracji, że zwrócone idosoby będzie id osoby najwyższej.

Zastnaów się nad takim zapytaniem:

Kod
SELECT MAX(wzrost) AS max, MIN(wzrost) AS min, SUM(wzrost) AS sum,idosoby
       FROM osoby o
       INNER JOIN dzialy d
       ON o.iddzialu = d.iddzialu
       GROUP BY d.iddzialu
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.