Guten Tag,
ich bin Neuling auf dem Gebiet und verzweifle an einer, so denke ich immer noch, einfachen Abfrage.
Im Anhang habe ich die besagte Tabelle angehangen.
Ziel ist es zum Beispiel den Messwert für das Jahr 1989 zu ermitteln. Dies ist nicht das Problem, jedoch wurde der Punkt “1017” auch im Jahr 1999 gemessen. Der soll daraufhin keine Berücksichtigung finden. Das Ergebnis soll nur den Punkt “1021” anzeigen.
Hier mein Ansatz:
select m.gp_nr, m.messwert from ta_messdaten m where m.datum BETWEEN ‘1989-01-01’ AND ‘1989-12-31’!
Das Ergebnis sind nun logischerweise beide Punkte, jedoch möchte ich auch nur den haben der keine spätere Messung mehr hat. Sprich den Punkt “1021”
Habe nun schon viel probiert und erhoffe mir hier einen denkanstoß zu bekommen.
Ich suche eigentlich nur die Punktnummer samt Messwert für ein bestimmtes Jahr, sagen wir mal 1989. Die ist ja kein Problem.
Gleichzeitg möchte ich aber jene Punkte ausschließen, die einen späteren Messwert noch besitzen.
Genauer bedeutet das für die angehangte Tabelle:
Punkt: 1021 wurde das letzte mal 1989 gemessen und soll als Ergebnis erscheinen.
Punkt 1017 wurde auch im Jahr 1989 gemessen, aber weiterhin auch in 1994, 1999. Deshalb soll er keine Berücksichtigung finden, sondern nur jene die auch das letzte mal gemessen wurden im definierten Jahr.
Ich hoffe ich konnte mich verständlicher ausdrücken
Danke!
select m.gp_nr,
m.messwert
from ta_messdaten m
where m.datum between date '1989-01-01' AND date '1989-12-31'
and not exists (select *
from ta_messdaten m2
where m2.datum > date '1989-12-31'
and m2.gp_nr = m.gp_nr);
(Ich bevorzuge die Schreibweise DATE ‘1989-01-01’ weil das ANSI SQL ist und ich nicht bei jedem DBMS umdenken muss)
Hallo, ich bin es nochmal. Danke für eure Antworten! Meine Ausgangslage hat sich nochmal geändert.
Ich muss zur Nullmessung (=1.Messung bzw. früheste Messung) eine Differenz berechnen.
Praktisch: 227.8710-227.9790
Den Code für die beiden Zahlen habe ich soweit hinbekommen. Nur schaffe ich es nicht beide zu integrieren das ich nur noch eine Anweisung habe.
Mein Ansatz:
select m.gp_nr, m.messwert from ta_messdaten m
where m.datum between date '1999-01-01' AND date '1999-12-31'
and not exists (select * from ta_messdaten m2 where m2.datum > date '1999-12-31'and m2.gp_nr = m.gp_nr);
–> liefert mir als Wert die 227.8710
SELECT m.gp_nr,m.datum,m.messwert FROM ta_messdaten m
WHERE m.datum = (
SELECT MIN(b.datum)
FROM ta_messdaten b
WHERE b.gp_nr = m.gp_nr and b.gp_nr='1017' )and m.gp_nr='1017'
–> Liefert mir als Wert: 227.9790
Jedoch möchte ich nicht beide ausführen, sondern gleich in der SQL Anweisung die Differenz berechnen.
Du suchst window-Funktionen. lag() z.B. liefert Dir innhalb eines Window bzw. Frame den Vorgänger (optional den nten Vorgänger), first_value den ersten Wert.
test=*# select * from sammer ;
g | o | val
---+---+-----
1 | 1 | 10
1 | 2 | 20
1 | 3 | 25
2 | 1 | 1
2 | 2 | 4
2 | 3 | 6
3 | 1 | 9
3 | 2 | 8
3 | 3 | 7
(9 rows)
test=*# select g, val, first_value(val) over (partition by g order by o), val - first_value(val) over (partition by g order by o) from sammer ;
g | val | first_value | ?column?
---+-----+-------------+----------
1 | 10 | 10 | 0
1 | 20 | 10 | 10
1 | 25 | 10 | 15
2 | 1 | 1 | 0
2 | 4 | 1 | 3
2 | 6 | 1 | 5
3 | 9 | 9 | 0
3 | 8 | 9 | -1
3 | 7 | 9 | -2
(9 rows)
g ist die Gruppe, o ein Sortiermerkmal innerhalb der Gruppe. rest: sieh Doku.
select m.gp_nr, m.messwert, first_value(a.messwert) over (partition by a.datum order by a.gp_nr)from ta_messdaten m, ta_messdaten a
where m.datum between date '1989-01-01' AND date '1989-12-31'
and not exists (select * from ta_messdaten m2 where m2.datum > date '1989-12-31' and m2.gp_nr = m.gp_nr )and m.gp_nr=a.gp_nr
Die Berechnung führt er soweit aus, mein Problem liegt jetzt darin, dass die 1. Berechnung passt, aber er den “first value” im weiteren verlauf einfach erhöht. Übersehe ich da ein Problem?
select m.gp_nr, m.messwert, first_value(a.messwert) over (partition by a.gp_nr order by a.gp_nr)from ta_messdaten m, ta_messdaten a
where m.datum between date '1989-01-01' AND date '1989-12-31'
and not exists (select * from ta_messdaten m2 where m2.datum > date '1989-12-31' and m2.gp_nr = m.gp_nr )and m.gp_nr=a.gp_nr
Die erste Zeile des Punktes 1021 passt, jedoch die erste Zeile des Punktes 1230 past nicht. Hier nimmt er beides mal den gleichen Wert, warum auch immer
select m.gp_nr, m.messwert, first_value(a.messwert) over (partition by a.gp_nr order by a.datum)from ta_messdaten m, ta_messdaten a
where m.datum between date '1989-01-01' AND date '1989-12-31' and m.gp_nr=a.gp_nr
and not exists (select * from ta_messdaten m2 where m2.datum > date '1989-12-31' and m2.gp_nr = m.gp_nr and m2.gp_nr=a.gp_nr and m.gp_nr=a.gp_nr )and m.gp_nr=a.gp_nr
Hier stimmen die Werte, aber die Menge der Ergebnis ist zu hoch. Eine Idee wie man das unterbinden kann.
so klappt es jetzt
select Distinct m.gp_nr, m.messwert, first_value(a.messwert) over (partition by a.gp_nr order by a.datum)from ta_messdaten m, ta_messdaten a
where m.datum between date '1989-01-01' AND date '1989-12-31' and m.gp_nr=a.gp_nr
and not exists (select * from ta_messdaten m2 where m2.datum > date '1989-12-31' and m2.gp_nr = m.gp_nr and m2.gp_nr=a.gp_nr and m.gp_nr=a.gp_nr )and m.gp_nr=a.gp_nr
So ich bin es nochmal. Habe ein weiteres Anliegen bezüglich meiner Aufgabe. Ich hoffe es wird nicht zu undurchsichtig.
Der unten stehende Code funktioniert eigentlich einwandfrei!
select Distinct m.gp_nr,k.rechtswert,k.hochwert, (m.messwert - first_value(a.messwert) over (partition by a.gp_nr order by a.datum)) as dif from ta_messdaten m, ta_messdaten a,ta_kopfdaten k where m.datum between date '2008-01-01' AND date '2008-12-31' and m.gp_nr=a.gp_nr and k.gp_nr=a.gp_nr and k.gp_nr=m.gp_nr and not exists (select * from ta_messdaten m2 where m2.datum > date '2008-12-31' and m2.gp_nr = m.gp_nr and m2.gp_nr=a.gp_nr and m.gp_nr=a.gp_nr )and m.gp_nr=a.gp_nr;
Um diesen aber zu verfeinern möchte ich eine weitere Klausel einbauen die folgendes bewirken soll:
Ich möchte die Rechnung unter Pkt. 2 ausschließen, da nur ein Messwert vorliegt. Es kommt immer 0 raus, was in meiner Anwendung dann keine Aussagekraft hat und entfallen soll.
Hier mein Ansatz: Habe versucht eine aggregatfunktion in der having methode einzubauen. Jedoch erhalte ich hier keine Lösungsmenge, was ich mir nicht erklären kann.
select Distinct m.gp_nr,k.rechtswert,k.hochwert, (m.messwert - first_value(a.messwert) over (partition by a.gp_nr order by a.datum)) as dif from ta_messdaten m, ta_messdaten a,ta_kopfdaten k where m.datum between date '2008-01-01' AND date '2008-12-31' and m.gp_nr=a.gp_nr and k.gp_nr=a.gp_nr and k.gp_nr=m.gp_nr and not exists (select * from ta_messdaten m2 where m2.datum > date '2008-12-31' and m2.gp_nr = m.gp_nr and m2.gp_nr=a.gp_nr and m.gp_nr=a.gp_nr )and m.gp_nr=a.gp_nr group by m.gp_nr,k.rechtswert,k.hochwert,m.messwert,a.messwert,a.gp_nr,a.datum
having COUNT (m.messwert)>1;
Falls hier noch einer durchsteigt freue ich mich auf eine Antwort. Danke!
Zähle, wie oft je Punkt gemessen wird. Ist das kleiner 2, dann ignoriere.
test=*# select * from foo;
punkt | jahr
-------+------
1 | 1990
1 | 1991
1 | 1992
2 | 1990
3 | 1990
3 | 1991
(6 rows)
Time: 0,142 ms
test=*# select * from foo where punkt in (select punkt from (select punkt, count(*) from foo group by punkt) bla wherecount >=2);
punkt | jahr
-------+------
1 | 1990
1 | 1991
1 | 1992
3 | 1990
3 | 1991
(5 rows)
Guten Tag allerseits,
bin gerade dabei mein SQL-Statement weiter zu verfeinern. Ich hoffe ich kann mein Problem anständig erläutern
Derzeit stellt er sich wie folgt dar:
"select Distinct m.gp_nr,k.rechtswert,k.hochwert, round((m.messwert - first_value(a.messwert) over (partition by a.gp_nr order by a.datum)),3) as dif from ta_messdaten m, ta_messdaten a,ta_kopfdaten k "
+ "where m.datum between date '"
+ jahr
+ "-01-01' AND date '"
+ jahr
+ "-12-31' and m.gp_nr=a.gp_nr and k.gp_nr=a.gp_nr and k.gp_nr=m.gp_nr "
+ "and not exists (select * from ta_messdaten m2 where m2.datum > date '"
+ jahr
+ "-12-31' and m2.gp_nr = m.gp_nr and m2.gp_nr=a.gp_nr and m.gp_nr=a.gp_nr )and m.gp_nr in (select gp_nr from ( select gp_nr,count(*) from ta_messdaten group by gp_nr) b where count >=2) and m.gp_nr=a.gp_nr order by m.gp_nr "
Diese Abfrage funktioniert auch so wie sie soll. Jetzt zu meinem Problem:
round((m.messwert - first_value(a.messwert)
Die oben zusehende Rechnung beruht auf zwei Messwerten. Jedoch gibt es eine weitere Spalte mit Messwerten, namens ‘Messwert interpoliert’. Jedoch ist immer nur eine der beiden gefüllt. Ferner möchte ich die Berechnung ändern, dass wenn m.messwert leer ist, er dafür m.messwert interpoliert nimmt.
Müsste man dies in mehrere Abfragen aufdröseln? Ich hoffe es ist verständlich andernfalls könnte ich ein Beispiel erzeugen.
Gruß Andi