sql >> Databáze >  >> RDS >> Mysql

Identifikace uživatelů s klesajícím trendem SQL

To je trochu složitější a k nalezení výsledků, které se neustále zvyšují nebo snižují, pravděpodobně budete chtít použít MATCH_RECOGNIZE klauzule, kterou MySQL (zatím) nepodporuje. Tímto způsobem můžete definovat vzor, ​​podle kterého je každé množství menší než předchozí hodnota. Navíc byste to pravděpodobně mohli udělat s rekurzivním cte, ale to by bylo mimo mé schopnosti.

Zde je to, na co jsem přišel, s výhradou, že porovnává pouze první a poslední hodnotu:

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ž dává:

CUSTOMER
Bob
Mary

Nebo, abyste dosáhli striktního snížení se známým maximem, můžete je všechny spojit dohromady, což je docela ošklivé:

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ž dává:

CUSTOMER
Mary

I když pro neznámou částku bych si myslel, že match_recognize by bylo nejlepším řešením (nebo byste mohli přidat nějakou rekurzi nebo vlastní funkci).



  1. Jak vybrat řádek maximální hodnoty v tabulce mysql

  2. mysql vyberte odlišný, ale nejnovější řádek

  3. SQL funkce - faktoriál

  4. Jaká je konvence pro použití JSONField (nativní postgres jsonb) v Django 1.9?