sql >> Databáze >  >> RDS >> PostgreSQL

Detekce ostrova SQL přes více parametrů a podmínek

Odpověď na aktualizovanou otázku

SELECT *
FROM  (
   SELECT *
         ,lag(val, 1, 0) OVER (PARTITION BY status ORDER BY id) last_val
         ,lag(status) OVER (PARTITION BY val ORDER BY id) last_status
   FROM   t1
   ) x
WHERE  status = 1
AND    (last_val <> val OR last_status = 0)

Jak?

Stejné jako dříve, ale tentokrát kombinuje dvě funkce okna. Zapnutí zařízení se kvalifikuje, pokud ..
1. poslední zapnuté zařízení bylo jiné jeden.
2. nebo bylo stejné zařízení vypnuto ve svém posledním záznamu. Rohové pouzdro s NULL pro první řádek oddílu je irelevantní, protože pak je řádek již kvalifikovaný v 1.

Odpověď pro původní verzi otázky.

Pokud správně rozumím vašemu úkolu, funguje tento jednoduchý dotaz:

SELECT *
FROM  (
   SELECT *
         ,lag(val, 1, 0) OVER (ORDER BY id) last_on
   FROM   t1
   WHERE  status = 1
   ) x
WHERE  last_on <> val

Vrátí řádky 1, 3, 6, 7 podle požadavku.

Jak?

Poddotaz ignoruje všechna vypínání, protože to je podle vašeho popisu pouze šum. Ponechává záznamy tam, kde je zařízení zapnuté. Z těch jsou diskvalifikovány pouze ty položky, kde již bylo zapnuto stejné zařízení (zapnutí posledního vstupu). Použijte funkci okna lag() pro to. Konkrétně uvádím 0 jako výchozí pokrýt speciální případ prvního řádku – za předpokladu, že neexistuje žádné zařízení s val = 0 .
Pokud existuje, vyberte jiné nemožné číslo.
Pokud žádné číslo není nemožné, ponechte speciální případ NULL s lag(val) OVER ... a ve vnějším dotazu zkontrolujte:

WHERE last_on IS DISTINCT FROM val



  1. Minimální hodnota dotazu MySQL

  2. Sequelize Najít patříToMany Association

  3. PRVG-2027 Vlastník souboru je mezi uzly nekonzistentní

  4. mysqli multi_query následovaný dotazem