Zakładamy że mamy taką oto tabelę:
Osoby
——-
idOsoby
Imie
Wiek
Nazwisko
oraz takie dane:
IdOsoby | Imie | Wiek | Nazwisko |
1 | Mateusz | 21 | Mazurek |
2 | Michał | 36 | Dorycki |
3 | Kamil | 37 | Dudło |
4 | Sebastian | 19 | Tabelowski |
5 | Łukasz | 12 | Wlazło |
6 | Maciej | 36 | Prędki |
Chciałbym wybrać z tej tabeli wiek osoby która jest młodsza od najstaszej osoby ale starsza od pozostałych osób.
Czyli druga wartość jeśli byśmy sortowali malejąco po wieku.
Skorzystamy z podzapytań (subqueries). Zapytanie wewnętrzne zwracać będzie 2 pierwsze rekordy z tych posortowanych malejąco, czyli od największego do najmniejszego. A z tego wyniku wybierzemy najmniejszą wartość.
Czyli z podzapytania weźmiemy:
IdOsoby | Imie | Wiek | Nazwisko |
3 | Kamil | 37 | Dudło |
2 | Michał | 36 | Dorycki |
A następnie z tego weźmiemy najmniejszą wartość wieku. Co będzie równoznaczne z 2 co do kolejności malejącej wartość wieku z całej tabeli :)
Zapytanie:
1 2 3 | SELECT MIN(Wiek) AS secondvalue FROM (SELECT TOP(2) * FROM dbo.Osoby ORDER BY Osoby.Wiek DESC) AS r |
Mateusz Mazurek
Przydało się, dziękuję
mi tez mordo
Wydaje mi się, choć mogę się mylić, że TOP(2) nie jest tu właściwym rozwiązaniem.
Sortując malejąco wiersze w tabeli (podzapytanie), otrzymujemy:
——————————-
Kamil Dudło 37
Michał Dorycki 36 ← wybieramy tą osobę
Maciej Predki 36 ← ale ta również jest dobrym kandydatem
——————————-
Moim zdaniem wynikiem zapytania powinny być obydwie w.w. osoby, ponieważ w zadaniu
nie mamy żadnego kryterium (kolejność alfabetyczna, długość imienia), żeby wybrać akurat
Michała Doryckiego.
Sprawa ma się podobnie do miejsc w rankingu w danych zawodach, jeśli 2 osoby mają po 1000 pkt, to
w rankingu są ex aeqo.
Wydaje mi się, że należy złączyć podaną tabelę z nią samą, tylko nie znakiem „=”, a „>”, natomiast tutaj kończy się moja intuicja, która mogłaby doprowadzić do poprawnego rozwiązania.
Byłbym wdzięczny za pomoc w znalezieniu rozwiązania.
Pozdrawiam, Wiktor : )
Cześć Wiktor! :)
Mimo że wpis jest z 2013 roku, czyli ma całe 7 lat, to zapytanie spełnia założenia, które brzmią „chciałbym wybrać z tej tabeli wiek osoby która jest młodsza od najstaszej osoby ale starsza od pozostałych osób.”. A w odniesieniu tego co piszesz to ja tutaj wybieram tylko wiek a ten dla osób które mają ten sam wiek, jest, co jest oczywiste – ten sam.
To co Ty potrzebujesz to nieco inny problem, ciężko mi pomóc konkretną sqlką bo tę wyżej pisałem w MsSql którego już nie używam, ale np. dla MySql’a mogłby to wygląda tak:
SELECT * from MyGuests where wiek = (SELECT wiek from MyGuests order by wiek limit 1 offset 1)
Mam nadzieję że to naprowadzi na rozwiązanie.
Pozdrawiam!
Faktycznie, po tym jak Pan odpisał jeszcze raz przeczytałem dokładnie o czym jest wpis na blogu. Generalnie mój problem brzmiał „Wybrać dane osób młodszych od najstarszej osoby, ale też starszych od reszty”. Problem został rozwiązany i jeśli to może się komuś przydać wrzucam zapytanie, które robi ranking uzwględniający miejsca ax aeqo:
[ 1 Sposób ]
SELECT wiek, imie, nazwisko
FROM Osoby O
WHERE (SELECT COUNT(DISTINCT wiek) FROM Osoby WHERE wiek > O.wiek) = 1;
[ 2 Sposób ]
SELECT A.wiek, A.imie, A.nazwisko, COUNT(DISTINCT B.wiek)
FROM Osoby A
LEFT JOIN Osoby B ON A.wiek < B.wiek
GROUP BY A.wiek, A.imie, A.nazwisko
HAVING COUNT(DISTINCT B.wiek) = 1
Usuwając HAVING z drugiego sposobu otrzymujemy pełny ranking osób w zależności od wieku. Jako, że może się to przydać innym może warto zrobić z tego osobny atrykuł? :)