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 |
Cześć. Dziś luźny artykuł, bo dziś pobawimy się jedną z pierwszy wersji Pythona. Skompilujemy go i zobaczymy co tam w… Read More
Nowy rok czas zacząć! Więc lećmy z podsumowaniem. Nowy artykuł Nie uwierzycie, ale pojawił się na blogu nowy artykuł! Piszę… Read More
Cześć! W Pythonie 3.13 dodano JITa! JIT, czyli just-in-time compiler to optymalizacja na która Python naprawdę długo czekał. Na nasze… Read More
Cześć! Zapraszam na podsumowanie roku 2024. Książki W sumie rok 2024 był pod względem ilości książek nieco podobny do roku… Read More
Podtrzymując tradycję, prawie regularnych podsumowań, zapraszam na wpis! Nie mogło obyć się bez Karkonoszy We wrześniu odwiedziłem z kolegą Karkonosze,… Read More
Oj daaawnoo mnie tu nie było. Ale wakacje to był czas dużej liczby intensywnych wyjazdów i tak naprawdę, dopiero jakoś… Read More
Pokaż komentarze
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ł? :)