Wybór największej wartości z wykorzystaniem funkcji ROW_NUMBER

0

Witam,
Mam tabelę "szkolenia" jak poniżej|

id data_rozpoczecia nazwa_szkolenia
1 2012-12-12 bhp
2 2013-12-12 sql
3 2014-12-12 bhp
4 2015-12-12 bhp

robię na niej zapytanie

SELECT id, data_rozpoczecia,
row_number () over (partition nazwa_szkolenia order by nazwa_szkolenia) as numer
from szkolenia
order by data_rozpoczecia

w wyniku dostaję

id | data_rozpoczecia | nazwa_szkolenia| numer
---------------- | -------------------
1 | 2012-12-12 | bhp | 1
3 | 2014-12-12 | bhp | 2
4 | 2015-12-12 | bhp | 3
2 | 2013-12-12 | sql | 4

Jak sformułować zapytanie tak aby została wybrane szkolenie z grupy bhp z najmłodszą datą czyli 2015-12-12 ???

0
SELECT TOP 1 id, data_rozpoczęcia
FROM szkolenia
WHERE nazwa_szkolenia = 'bhp'
ORDER BY data_rozpoczęcia DESC

albo

SELECT id, data_rozpoczęcia
FROM szkolenia
WHERE data_rozpoczęcia = (SELECT MAX(data_rozpoczęcia) FROM szkolenia WHERE nazwa_szkolenia = 'bhp')
0
  1. Na peno ROW_NUMBER() nie zwróci 'bhp'
  2. Partition by i order by po tym samym polu są bez sensu. Powinno być order by data_szkolenia
  3. Order by 3 (gdzie 3 to numer kolumny w wyniku)
  4. Limit
0
Marcin.Miga napisał(a):
  1. Na peno ROW_NUMBER() nie zwróci 'bhp'
  2. Partition by i order by po tym samym polu są bez sensu. Powinno być order by data_szkolenia
  3. Order by 3 (gdzie 3 to numer kolumny w wyniku)
  4. Limit

Kolega ma rację poprawnie będzie ;

SELECT id, data_rozpoczecia,nazwa_szkolenia,
ROW_NUMBER () OVER (partition by nazwa_szkolenia ORDER BY nazwa_szkolenia) AS numer
FROM szkolenia

Wtedy otrzymam:
screenshot-20170828212424.png

Problemu nie ma dla wąskiego zakresu danych ale w przypadku większej ilości rodzaju szkoleń, gdzie jedna osoba (ID) może mieć ich kilka. Jak z takiej grupy wybrać najmłodsze (tak żeby tylko one były wyświetlone). Czy można wybrać maksymalną wartość z ```sql
ROW_NUMBER

0
Haskell napisał(a):
SELECT TOP 1 id, data_rozpoczęcia
FROM szkolenia
WHERE nazwa_szkolenia = 'bhp'
ORDER BY data_rozpoczęcia DESC

albo

SELECT id, data_rozpoczęcia
FROM szkolenia
WHERE data_rozpoczęcia = (SELECT MAX(data_rozpoczęcia) FROM szkolenia WHERE nazwa_szkolenia = 'bhp')

Kalega ma rację. A co jeśli nie znam nazwy_szkolenia? System sam grupuje po BHP i niech wybierze najmłodsze?

0

Jeżeli ma zwrócić najmłodsze szkolenie to z warunku usuń where nazwa_szkolenia.

0
Haskell napisał(a):

Jeżeli ma zwrócić najmłodsze szkolenie to z warunku usuń where nazwa_szkolenia.

Najmłodsze szkolenie z danej grupy szkoleń dla konkretnego ID

0

Jeżeli ma być dla konkretnej grupy szkoleń to wystarczy pogrupować.

0

Tu się poddaję? Coś więcej można?

0

GROUP BY po nazwa_szkolenia, a w SELECT dajesz MAX(data_szkolenia).

0
SELECT id, data_rozpoczecia,nazwa_szkolenia,
ROW_NUMBER () OVER (partition by id ORDER BY nazwa_szkolenia) AS numer
FROM szkolenia
group by id, data_rozpoczecia,nazwa_szkolenia

to nie to :(

1
SELECT MAX(data_rozpoczecia), nazwa_szkolenia
FROM szkolenia
GROUP BY nazwa_szkolenia
0

Super dzięki to je to :)

0

A czy można w ogóle sortować po kolumnie numer w wywołaniu ROW_NUMBER??

0

Można. Po numerze kolumny wynikowej. Np. ORDER BY 3

1

Można dać WHERe na row_number

select
    *
from (SELECT id, data_rozpoczecia,nazwa_szkolenia,
ROW_NUMBER () OVER (partition BY nazwa_szkolenia ORDER BY data_szkolenia DESC) AS numer
FROM szkolenia) dt
where numer = 1
0
  1. ROW_NUMBER() - Numerujesz wiersze w obrębie grupy
  2. PARTITION BY - tym dzielisz na grupy
  3. ORDER BY - tym porządkujesz w ramach grupy

Ad. 2
Osoba (ID) może brać udział w wielu szkoleniach i wielokrotnie w tym samym szkoleniu, czyli dzielisz grupę po id i nazwie szkolenia
PARTITION BY ID,NAZWA_SZKOLENIA

Ad.3
Grupę sortujesz po dacie rozpoczęcia (jak tam chcesz czy rosnąco czy malejąco)

select * from (select t.*, row_number() over (partition by id, nazwa_szkolenia order by data_rozpoczecia desc) rn from szkolenia) where rn=1;

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