sql >> Database >  >> RDS >> PostgreSQL

Detecteer SQL-eiland over meerdere parameters en voorwaarden

Antwoord voor bijgewerkte vraag

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)

Hoe?

Hetzelfde als voorheen, maar deze keer twee vensterfuncties combineren. Het inschakelen van een apparaat komt in aanmerking als ..
1. het laatst ingeschakelde apparaat was een andere een.
2. of hetzelfde apparaat is uit uitgeschakeld in zijn laatste invoer. De hoekkast met NULL voor de eerste rij van de partitie is niet relevant, omdat de rij dan al gekwalificeerd is in 1.

Antwoord voor originele versie van vraag.

Als ik uw taak goed begrijp, doet deze eenvoudige vraag het werk:

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

Retourneert rijen 1, 3, 6, 7 zoals gevraagd.

Hoe?

De subquery negeert alle uitschakelen, want dat is gewoon ruis, volgens uw beschrijving. Laat vermeldingen achter waar een apparaat is ingeschakeld. Daarvan worden alleen die inzendingen gediskwalificeerd, waarbij hetzelfde apparaat al was ingeschakeld (de laatste inzending wordt ingeschakeld). Gebruik de vensterfunctie lag() daarom. In het bijzonder geef ik 0 standaard om het speciale geval van de eerste rij te dekken - ervan uitgaande dat er geen apparaat is met val = 0 .
Als dat zo is, kies dan een ander onmogelijk nummer.
Als geen nummer onmogelijk is, laat het speciale geval als NULL met lag(val) OVER ... en in de buitenste vraag controleer met:

WHERE last_on IS DISTINCT FROM val



  1. Hoe genereer je een unieke id in MySQL?

  2. Een JDBC ResultSet toewijzen aan een object

  3. Ondersteunt MySQL door de gebruiker gedefinieerde gegevenstypen?

  4. Laravel-project ERR_EMPTY_RESPONSE