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

SQL funkcje okna

Cloud VPS
0 głosów
695 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 Mentor (354,120 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 430 wizyt
0 głosów
1 odpowiedź 303 wizyt
pytanie zadane 25 października 2024 w SQL, bazy danych przez sisOOO Obywatel (1,430 p.)
+1 głos
3 odpowiedzi 300 wizyt
pytanie zadane 13 marca 2024 w SQL, bazy danych przez Ppaat Nowicjusz (130 p.)

93,460 zapytań

142,454 odpowiedzi

322,724 komentarzy

62,837 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

Kursy INF.02 i INF.03
...