Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8549311
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 11, 20262026-06-11T13:41:33+00:00 2026-06-11T13:41:33+00:00

(PostgreSQL 8.4) I got a great introduction to SQL gaps-and-islands here on Stack Overflow

  • 0

(PostgreSQL 8.4) I got a great introduction to SQL gaps-and-islands here on Stack Overflow but I still have a question. Many island detection CTEs are based on a running order of a timestamp and some flag which breaks the sequence when it changes. But what if the "break" condition is a little more complex?

CREATE TABLE T1
(
  id SERIAL PRIMARY KEY,
  val INT,   -- some device
  status INT -- 0=OFF, 1=ON
);

INSERT INTO T1 (val, status) VALUES (10, 1);
INSERT INTO T1 (val, status) VALUES (10, 0);
INSERT INTO T1 (val, status) VALUES (11, 1);
INSERT INTO T1 (val, status) VALUES (11, 1);
INSERT INTO T1 (val, status) VALUES (10, 0);
INSERT INTO T1 (val, status) VALUES (12, 1);
INSERT INTO T1 (val, status) VALUES (13, 1);
INSERT INTO T1 (val, status) VALUES (13, 0);
INSERT INTO T1 (val, status) VALUES (13, 1);

In this case, val represents a device, and status is either ON or OFF. I want to select records 1, 3, 6, 7 and 9 with the following logic.

  1. #10 turns ON — OK, new sequence, include in SELECT
  2. #10 turns OFF — ends sequence properly, ignore row
  3. #11 turns ON — OK, new sequence, include in SELECT
  4. #11 turns ON — duplicate, ignore row
  5. #10 turns OFF — #10 wasn’t ON, ignore
  6. #12 turns ON — OK, implicitly turns OFF #11, include in SELECT
  7. #13 turns ON — OK, implicitly turns OFF #12, include in SELECT
  8. #13 turns OFF — ends sequence properly, ignore row
  9. #13 turns ON — OK, new sequence, include in SELECT

Basically, only one device can be ON at a time, and the "break" condition is that:

  • new.val = running.val AND new.status = 0
  • new.val <> running.val AND new.status = 1

I’m looking for something in the form of a CTE, no cursors please.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-11T13:41:33+00:00Added an answer on June 11, 2026 at 1:41 pm

    Answer for updated question

    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)
    

    How?

    Same as before, but this time combine two window functions. Switching on a device qualifies if ..
    1. the last device switched on was a different one.
    2. or the same device has been switched off in its last entry. The corner case with NULL for the first row of the partition is irrelevant, because then the row already qualified in 1.


    Answer for original version of question.

    If your I understand your task correctly, this simple query does the job:

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

    Returns rows 1, 3, 6, 7 as requested.

    How?

    The subquery ignores all switching off, as that is just noise, according to your description. Leaves entries where a device is switched on. Among those, only those entries are disqualified, where the same device was on already (the last entry switching on). Use the window function lag() for that. In particular I provide 0 as default to cover the special case of the first row – assuming that there is no device with val = 0.
    If there is, pick another impossible number.
    If no number is impossible, leave the special case as NULL with lag(val) OVER ... and in the outer query check with:

    WHERE last_on IS DISTINCT FROM val
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I've got two PostgreSQL databases that have been created using the same sql file.
Here's the problem. I've got two different technologies needing drivers to access a PostgreSQL
PostgreSQL / Django / newbie here. I've got a bunch of JSON data with
This question is about Postgresql 8.3 . I've got a table with a field
I am a beginner with PostgreSQL. I got a SQL patch of PostgreSQL and
I'm trying to startup my PostgreSQL server on my local machine. But I got
Hy guys, i have a postgresql 8.3 server with many database. Actually, im planning
I am using postgresql 8.3 and I have a simple sql query: SELECT a.id,a.bpm_process_instance_id,a.actor_id
I have a database in PostgreSQL. And I have sql query (which btw works
I am compiling PHP and PostgreSQL myself. I have got things working fine. There

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.