Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Identyfikacja użytkowników z trendem spadkowym SQL

Jest to trochę trudne i aby znaleźć wyniki, które stale rosną lub maleją, prawdopodobnie będziesz chciał użyć MATCH_RECOGNIZE klauzula, której MySQL nie obsługuje (jeszcze). W ten sposób możesz zdefiniować wzorzec, w którym każda ilość jest mniejsza niż poprzednia wartość. Dodatkowo prawdopodobnie mógłbyś to zrobić za pomocą rekurencyjnego cte, ale byłoby to poza moimi możliwościami.

Oto, co wymyśliłem, z zastrzeżeniem, że porównuje tylko pierwszą i ostatnią wartość:

WITH
    tbl (customer, purchasedate, quantity) AS (
SELECT * FROM VALUES 
    ('Bob',         '9/1/2021',        10),
    ('Bob',         '9/10/2021',       6),
    ('Bob',         '9/18/2021',       5),
    ('Bob',         '9/19/2021',       8),
    ('Mary',        '9/1/2021',        10),
    ('Mary',        '9/10/2021',       6),
    ('Mary',        '9/18/2021',       5),
    ('Mary',        '9/19/2021',       3),
    ('Frank',       '9/1/2021',        5),
    ('Lucus',       '9/1/2021',        5),
    ('Lucus',       '9/10/2021',       6),
    ('Lucus',       '9/18/2021',       10)
)

SELECT
    DISTINCT customer
FROM
    tbl
QUALIFY
      FIRST_VALUE(quantity) OVER (partition BY customer ORDER BY purchasedate)
    > LAST_VALUE(quantity)  OVER (PARTITION BY customer ORDER BY purchasedate)

Co daje:

CUSTOMER
Bob
Mary

Lub, aby ściśle zmniejszyć ze znanym maksimum, możesz połączyć je wszystkie razem, co jest dość brzydkie:

WITH
    tbl (customer, purchasedate, quantity) AS (
SELECT * FROM VALUES 
    ('Bob',         '9/1/2021',        10),
    ('Bob',         '9/10/2021',       6),
    ('Bob',         '9/18/2021',       5),
    ('Bob',         '9/19/2021',       8),
    ('Mary',        '9/1/2021',        10),
    ('Mary',        '9/10/2021',       6),
    ('Mary',        '9/18/2021',       5),
    ('Mary',        '9/19/2021',       3),
    ('Frank',       '9/1/2021',        5),
    ('Lucus',       '9/1/2021',        5),
    ('Lucus',       '9/10/2021',       6),
    ('Lucus',       '9/18/2021',       10)
)

SELECT
    DISTINCT customer
FROM
    tbl
    qualify 
        (NTH_VALUE(quantity, 1) OVER (partition BY customer ORDER BY purchasedate) >= NTH_VALUE(quantity, 2) OVER (partition BY customer ORDER BY purchasedate))
        and ((NTH_VALUE(quantity, 2) OVER (partition BY customer ORDER BY purchasedate) >= NTH_VALUE(quantity, 3) OVER (partition BY customer ORDER BY purchasedate)) or (NTH_VALUE(quantity, 3) OVER (partition BY customer ORDER BY purchasedate) is null))
        and ((NTH_VALUE(quantity,3) OVER (partition BY customer ORDER BY purchasedate) >= NTH_VALUE(quantity, 4) OVER (partition BY customer ORDER BY purchasedate)) or (NTH_VALUE(quantity, 4) OVER (partition BY customer ORDER BY purchasedate) is null))

Co daje:

CUSTOMER
Mary

Chociaż za nieznaną kwotę pomyślałbym, że match_recognize byłoby najlepszym rozwiązaniem (lub możesz dodać rekurencję lub funkcję niestandardową).



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Błąd Mysql InnoDB 32 w systemie Windows

  2. wstaw, jeśli nie istnieje, po prostu wybierz w mysql

  3. Jak uzyskać miesiąc używając daty w MySQL?

  4. Czy możliwe jest posiadanie kolumny MySQL zawierającej wiele wartości jako klucze obce?

  5. Błąd relacji Laravela:niezdefiniowana właściwość:Illuminate\Database\Eloquent\Collection::$id w wierszu 1