select Abfrage Hilfe

Hallo pg- Forum Community,

da ich mit postgresql nicht so vertraut bin wollte ich mal hier meine Frage reinstellen, ich hoffe ihr könnt mir helfen.
Also was habe ich
eine Spalte mit Jahresdaten (mehrfach und einmal) vorhanden

jahresdaten

2001
2002
2001
1984
1945
etc.

was ich bis jetzt geschaft habe ist diese zu Ordnen und mir die Anzahl ausgeben zu lassen in etwa so.

jahresdaten|Anzahl|
-----------±-----+
1945------|1------|
1984------| 29----|
etc.

Select-Anweisung bis jetzt:
select jahreszahl, count(jahreszahl) As Anzahl from tabelle group by jahresdaten oder by jahresdaten

Ziel.
eine Ansicht zu erhalten die bestimmt Bereich abdeckt. Also alle Treffer counted die im Bereich startDatum | endDatum liegen.
Es muss also mit Between 1945 and 1984 gearbeitet werden …
So bekomm ich zumindest eine Zeitspanne, jetz brauch ich aber min. 4 Zeitspannen :frowning:
In etwas so

startDatum|endDatum|AnzahlGesamt|
-----------±--------±------------|
1945------|1984-----|103----------|
etc.

wie kann ich sowas umsetzen ? Vielen Dank, schonmal für eure Hilfe
sam

So ganz klar ist mir nicht, was Du erreichen willst, aber vielleicht hilft Dir folgendes schon weiter:

test=*# select * from zeiten;
 jahr
------
 2001
 2002
 2001
 1984
 1945
 1945
(6 rows)

test=*# select jahr, sum(case when jahr between 1945 and 1984 then 1 else 0 end)as "zwischen 1945 und 1984", sum(case when jahr between 1984 and 1990 then 1 else 0 end) as "zwischen 1984 und 1990" from zeiten group by jahr order by jahr;
 jahr | zwischen 1945 und 1984 | zwischen 1984 und 1990
------+------------------------+------------------------
 1945 |                      2 |                      0
 1984 |                      1 |                      1
 2001 |                      0 |                      0
 2002 |                      0 |                      0
(4 rows)

Andreas

hey danke für die schnelle Antwort,

also was ich erreichen will vielleicht um es besser zu verstehen.

Ich möchte nachher eine Unterteilung in Kinder, Teenager, Erwachsene, Rentner haben.
Diese definiere ich nach ihrem Geburtsjahrgang
also sowas in der der Art

zwischen 1945 und 1984 | zwischen 1985 und 1999
------------------------±-----------------------
247 | 1239

Dann speichere doch ganz einfach das Geburtsdatum und verwende die AGE()-Funktion:

test=*# select name, geb_datum, age(geb_datum), case when extract(year from age(geb_datum)) < 10 then 'Kind' else 'nicht kind' end from kinder ;
  name  | geb_datum  |           age            |    case
--------+------------+--------------------------+------------
 kind1  | 2000-01-01 | 7 years 6 mons 23 days   | Kind
 kind2  | 2002-01-01 | 5 years 6 mons 23 days   | Kind
 mutter | 1970-08-01 | 36 years 11 mons 23 days | nicht kind
(3 rows)

Du kannst das im case … natürlich auf weitere Bedingungen ausbauen.

Andreas

hu akretschmer

Problem :confused: ich hatte vergessen zu sagen das die Daten als charachter varying gespeichert sind und nicht als Date :frowning: …(ließ sich nicht anders regeln).

Danke trozdem,
sam

Das ist suboptimal, aber nicht hoffnungslos:

test=*# select to_date('2005'::varchar, 'yyyy');
  to_date
------------
 2005-01-01
(1 row)

Andreas

Die Daten werden später in asp.net weiterverarbeitet, daher würde ich gerne
den Datentyp so belassen.

Mir würd es quasi reichen, wenn ich eine Spaltenstruktur hinbekomme die einfach nur die Ergebnisse untereinander in Zeilen ausgibt.

Also im Grunde sowas wie select count(jahr) from datum where jahr between 1985 and 1999
und das 4x jeweils einmal für die jeweilige Altersklasse zusammengefasst inner einer Abfrage

in etwa so

Anzahl|
------+
200   |
300   | 
etc.

Nochmals vielen Danke für die bisherige Hilfe,
sam

Dann mache Deine 4 Selects und verbinde die Resultate mit UNION ALL.

Andreas

ok danke akretschmer
das funktioniert soweit :wink:
sieht jetzt zwar nach quick and dirty aus, falls du noch ne idee hast wie ich das schöner hinbekomme, da sich bei mir ja nur die Between Werte ändern wäre ich dir sehr verbunden.
mfg,
sam

Es sieht zumindest schöner aus als für Jahreszahlen Strings zu verwenden… Das ist dann auch eine tickende Zeitbombe, weil mit jedem Geburtstag bzw. jedes Jahr ist die Query anzupassen. ( es si denn, Du hantierst mit age() oder so wie von mit gezeigt).

Andreas

ja im Moment ist es so, dass ich mit der Methode year(now) unter vb die Anpassung der between Werte durchführe…

dies könnte wie du oben schon geposted hast, ja auch die Datenbank übernehmen hmmmm

Ich denk mal drüber nach…

das Problem, was ich auf anhieb dabei habe ist glaub ich das automatisierte Umwandeln meiner varchar- Werte. Wie soll das gehen ? :frowning:
Gruß,
sam

Meinst Du jetzt das Ändern des Spaltentypes von TEXT auf DATE?

test=# create table zeiten ( j text);
CREATE TABLE
test=*# insert into zeiten values ('2001');
INSERT 0 1
test=*# alter table zeiten alter column j type date using cast(to_date(j, 'yyyy') as date);
ALTER TABLE
test=*# \d zeiten
   Table "public.zeiten"
 Column | Type | Modifiers
--------+------+-----------
 j      | date |

test=*# select * from zeiten ;
     j
------------
 2001-01-01
(1 row)

Andreas

Hi,
genau das meine ich
ich habe nochmal ein bisschen rumprobiert und die Daten werden jetzt wie folgt abgespeichert.

datum (Datentyp: text)|
----------------------+
2001-01-10
2000-01-13
2000-03-24
usw.

Und diesen Datensatz in der Spalte Datum würde ich jetzt gerne als Datentyp : date
vorliegen haben.
Meine Idee war jetzt eine neue Spalte vom Typ Date anzulegen und die Werte von der Spalte(datum) dort hineinzukopieren.
Dieses scheitert jedoch an meinen sql Kenntnissen *g.
Hast du da ne Idee ??
Vielen Dank,
Simon



test=*# create table zeiten ( j text);
CREATE TABLE
test=*# insert into zeiten values ('2001-08-01');
INSERT 0 1
test=*# alter table zeiten alter column j type date using cast(to_date(j, 'yyyy-mm-dd') as date);
ALTER TABLE
test=*# select * from zeiten ;
     j
------------
 2001-08-01
(1 row)

jop hab ich gerade auch gesehen :stuck_out_tongue: die eine CodeZeile muss ich wohl irgendwie überlesen haben.
Funktioniert super!
Vielen DANK!!
Simon