Abfrage Zeitraum

Moin,

ich habe ein kleines Problem. Ganz normale Abfrage eines Zeitraumes über das Datum.

SELECT * FROM tbl WHERE datum BETWEEN '2015-01-01' AND '2015-01-03'

Bekomme ich z.B. 5 Datensätze. Nun möchte ich aber nicht den jüngsten und ältesten Datensatz. In anderen SQLs schließt BETWEEN diese Datensätze eh aus. Wie kann ich das hier umsetzen?

Danke im vorraus.
chs

In dem Fall kannst Du kein BETWEEN verwenden:

SELECT * 
FROM tbl 
WHERE datum > DATE '2015-01-01' 
  AND datum < DATE '2015-01-03'



Welche anderen “SQL Statements” meinst Du denn?

Moin,

meine Beschreibung war nicht ausreichend. Jetzt sehe ich das auch. Es ist so, dass pro Tag theoretisch nur ein Datensatz existiert, nun wurden aber versehentlich mehrere erzeugt. Nun muss ich alle Datensätze dieses Zeitraumes löschen, bis auf den ersten und den letzten. Wichtig ist, dass das die Datumsspalte “timestamp with tz” ist.

hat die Tabelle einen PK?

mal als kleine spielerei…

test=# select * from chs;
           ts
------------------------
 2015-01-01 08:00:00+01
 2015-01-01 09:00:00+01
 2015-01-01 10:00:00+01
 2015-01-01 12:00:00+01
 2015-01-01 17:00:00+01
 2015-01-01 22:00:00+01
 2015-01-02 08:00:00+01
 2015-01-02 09:00:00+01
 2015-01-02 13:00:00+01
 2015-01-02 16:00:00+01
 2015-01-02 23:00:00+01
(11 rows)

test=*#  select *, row_number() over (partition by ts::date order by ts) as min, row_number() over (partition by ts::date order by ts desc) as max from chs ;
           ts           | min | max
------------------------+-----+-----
 2015-01-01 22:00:00+01 |   6 |   1
 2015-01-01 17:00:00+01 |   5 |   2
 2015-01-01 12:00:00+01 |   4 |   3
 2015-01-01 10:00:00+01 |   3 |   4
 2015-01-01 09:00:00+01 |   2 |   5
 2015-01-01 08:00:00+01 |   1 |   6
 2015-01-02 23:00:00+01 |   5 |   1
 2015-01-02 16:00:00+01 |   4 |   2
 2015-01-02 13:00:00+01 |   3 |   3
 2015-01-02 09:00:00+01 |   2 |   4
 2015-01-02 08:00:00+01 |   1 |   5
(11 rows)

test=*# with tmp as (select *, row_number() over (partition by ts::date order by ts) as min, row_number() over (partition by ts::date order by ts desc) as max from chs) delete from chs where ts in (select ts from tmp where min> 1 and max>1) ;
DELETE 7
test=*# select * from chs;
           ts
------------------------
 2015-01-01 08:00:00+01
 2015-01-01 22:00:00+01
 2015-01-02 08:00:00+01
 2015-01-02 23:00:00+01
(4 rows)

So aus der Hüfte geschossen, vielleicht etwas in dieser Richtung:

delete from the_table
where pk_column in (
          select pk_column
          from (
            select pk_column, 
                   row_number() over (partition by datum::date order by datum) as rn,
                   count() over (partition by datum::date) as day_count
            from the_table
           ) t
           where rn <> 1 and rn <> day_count
      );

“pk_column” ist der Primärschlüssel.
Wenn der aus mehr als einer Spalte besteht, dann eben mit “where (col1, col2) in (select col1, col2 …”

Aber ohne weitere Details zu der Tabelle ist das wirklich schwierig zu beantworten.

Hallo liebe Menschen,

Die Lösung von akretschmer hat zu 100% funktioniert.
Danke akretschmer und castorp für eure Mühen!