sql >> Database >  >> RDS >> Mysql

Gebruikers identificeren met een neerwaartse trend SQL

Dit is een beetje lastig, en om resultaten te vinden die gestaag toenemen of afnemen, zou je waarschijnlijk de MATCH_RECOGNIZE clausule, die MySQL (nog) niet ondersteunt. Op deze manier kunt u een patroon definiëren waarbij elke hoeveelheid kleiner is dan de vorige waarde. Bovendien zou je dit waarschijnlijk kunnen doen met een recursieve cte, maar dat zou buiten mijn mogelijkheden liggen.

Dit is wat ik bedacht, met het voorbehoud dat het alleen de eerste en laatste waarden vergelijkt:

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)

Wat geeft:

CUSTOMER
Bob
Mary

Of, om strikt te verminderen met een bekende max, je kunt ze allemaal aan elkaar koppelen, wat behoorlijk lelijk wordt:

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))

Wat geeft:

CUSTOMER
Mary

Hoewel ik voor een onbekend bedrag zou denken dat match_recognize zou de beste oplossing zijn (of je zou wat recursie of een aangepaste functie kunnen toevoegen).



  1. Meta-commando's in Psycopg2 - \d werkt niet

  2. invoegen bij dubbele sleutelupdate

  3. Hoe roep ik een databasefunctie aan met SQLAlchemy in Flask?

  4. MEDIAN gebruiken naast de MAX-, MIN- en AVG-functies in MySQL