• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

SQL funkcje okna

Object Storage Arubacloud
0 głosów
293 wizyt
pytanie zadane 2 lutego 2023 w SQL, bazy danych przez Blds Użytkownik (830 p.)

Próbuję wyciągnąć z bazy ostatni rating klienta przez funkcję okna. Ostatni rating jest okreśony przez kolumnę data ratingu. Jak mogę to wyciągnąć przez funkcję okna. Co mogę poprawić w poniższym kodzie, Może zamiast max, dać last value?

SELECT customer,
       rating,
       max(data_ratingu) OVER (PARTITION BY customer_id)
FROM
          (SELECT c.customer_id,
               rt.rating,
               rt.data_ratingu
             FROM cutomer AS c
            INNER JOIN rating_table AS rt ON c.customer_id = rt.customer_id) as a

 

komentarz 2 lutego 2023 przez adrian17 Ekspert (344,860 p.)
Jakby co, mysql ma tutaj w dokumentacji na końcu:

https://dev.mysql.com/doc/refman/8.0/en/example-maximum-column-group-row.html

1 odpowiedź

+1 głos
odpowiedź 3 lutego 2023 przez areklipno Stary wyjadacz (11,930 p.)
edycja 4 lutego 2023 przez areklipno

Wg mnie w ten sposób tego nie osiągniesz. Potrzebujesz wyciągnąć max(data_ratingu), ale grupowane tylko po customer_id. I wtedy dopiero połączyć, gdzie customer_id=customer_id i data_ratingu = (ten obliczony max).

Jeśli będziesz miał problem to napisać mogę pomóc.

edit:

Przykladowy sposób rozwiązania (mam nadzieję, że nie ma błędu w składni bo nie miałem gdzie przetestować):

with dane as (
			SELECT c.customer_id, rt.rating, rt.data_ratingu
			FROM cutomer AS c
			INNER JOIN rating_table AS rt ON c.customer_id = rt.customer_id
			)
, maksy as (
			select customer_id, max(data_ratingu) max_data
			from dane
			group by customer_id
)

select d.customer_id, d.rating, d.data_ratingu
from dane d
join maksy m on (m.customer_id = d.customer_id and d.data_ratingu = m.max_data)

 

 

komentarz 3 lutego 2023 przez Blds Użytkownik (830 p.)
A mógłbys to rozpisać? Docelowo chciałbym uzyskać tylko customerów z konkretnym ratingiem. Np 'A'. Właściwie pogrupowanych po ratingu. Pewnie mógłbym uzyskać to unionem. A jakiś inny sposób?
komentarz 4 lutego 2023 przez areklipno Stary wyjadacz (11,930 p.)
edytowałem post, żeby pokazać przykładowy kod
komentarz 6 lutego 2023 przez Blds Użytkownik (830 p.)

@areklipno, Wielkie  dzięki! zadziałało tak jak chciałem.

komentarz 7 lutego 2023 przez Blds Użytkownik (830 p.)
A moze ktoś ma pomysł dlaczego jak dodaję dodatkowe filtrowanie w zapytaniu to dostaję inne wyniki niż jak nie dam tego warunku, a odfiltruję sobie w excelu?
komentarz 8 lutego 2023 przez areklipno Stary wyjadacz (11,930 p.)
musiałbyś powiedzieć jakie warunki i gdzie dodajesz bo to ma duże znaczenie
komentarz 8 lutego 2023 przez Blds Użytkownik (830 p.)

Czyli do kodu zamieszczonego przez areklipno dodaję jeszcze jedną tabele  w with dane z adresem bo chcę dociągnąć kraj klienta. W tej tabeli klient występuje podwójnie bo ma adres korespondencyjny i rejestracji wiec żeby nie dublować klientów chce ograniczyć wynik tylko do klientów z np. adresem rejestracji. Jak dodam ten warunek to otrzymam inne wynik niż jak nie dodam, a filtr później założę w excelu

 

with dane as (
            SELECT c.customer_id, rt.rating, rt.data_ratingu
            FROM cutomer AS c
            INNER JOIN rating_table AS rt ON c.customer_id = rt.customer_id
            INNER JOIN customer_address AS ca ON c.customer_id = ca.customer_id
            WHERE type = 'registered'
            )
, maksy as (
            select customer_id, max(data_ratingu) max_data
            from dane
            group by customer_id
)
 
select d.customer_id, d.rating, d.data_ratingu
from dane d
join maksy m on (m.customer_id = d.customer_id and d.data_ratingu = m.max_data)

 

komentarz 8 lutego 2023 przez Blds Użytkownik (830 p.)

Zrobiłem modyfikację tego kodu i dodałem jeszcze jednego with as z tabelą z adresem, a ten warunek z pierwszego with as wyrzuciłem i mam coś takiego, ale wydaje mi się, że ten ostatni join jest coś nie tak. 

, adres AS (
            SELECT ca.customer_id, country_code
            FROM customer_address AS ca
            WHERE type = 'registered')

SELECT d.score, d.customer_id, d.email, d.name, d.phone_number , a.country_code
FROM dane AS d
JOIN maksy AS m ON (m.customer_id = d.customer_id and d.created = m.max_data)
JOIN adres AS a on (a.customer_id = d.customer_id)

ORDER BY d.score

 

komentarz 8 lutego 2023 przez areklipno Stary wyjadacz (11,930 p.)

Wg mnie wersja z CTE adres i joinem na końcu jest lepsza.

Żeby sprawdzić czy join Ci nic nie psuje zamień na

with dane as (
            SELECT c.customer_id, rt.rating, rt.data_ratingu
            FROM cutomer AS c
            INNER JOIN rating_table AS rt ON c.customer_id = rt.customer_id
            )
, maksy as (
            select customer_id, max(data_ratingu) max_data
            from dane
            group by customer_id
), adres AS (
            SELECT ca.customer_id, country_code
            FROM customer_address AS ca
            WHERE type = 'registered')
 
select d.customer_id, d.rating, d.data_ratingu
from dane d
join maksy m on (m.customer_id = d.customer_id and d.data_ratingu = m.max_data)
left join adres a on (a.customer_id = d.customer_id)
where a.country_code is null

Jeśli cokolwiek wyjdzie tzn. że jacyś klienci nie łączą Ci się na "join" - może np .nie mają adresu typu 'registered'

Podobne pytania

0 głosów
0 odpowiedzi 237 wizyt
+1 głos
3 odpowiedzi 122 wizyt
pytanie zadane 13 marca w SQL, bazy danych przez Ppaat Nowicjusz (130 p.)
+2 głosów
1 odpowiedź 101 wizyt

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...