SQL MySQL coalesce mit weiterem Kriterium

#1
Guten Tag zusammen,

Zu meinem Problem, ich habe zwei Tabellen die den selben Aufbau haben

Tabelle1 : id, all, wert, bemerkung, datum
Tabelle2 : id, all, wert, bemerkung, datum

In beiden Tabellen können die selben Werte drin stehen, müssen sich aber nicht zwangsläufig decken,... diese Art der zusammenführung würde ich mit COALESCE(tabelle1.wert, tabelle2.wert) und COALESCE(tabelle1.bermerkung, tabelle2.bemerkung) hinbekommen, allerdings möchte ich im Fall, dass die Spalten "all" sich gleichen, dass die entsprechende Zeile aus der Tabelle, in welcher das größere Datum steht, genommen wird. Müsste mit greatest(tabelle1.datum, tabelle2.datum) gehen.
Datum ist im Unix-Timestamp Format.

Ich weiß nur nicht wie ich das unter einen Hut bekomme.... :/

Kann mir jemand sagen wie ich das gelöst bekomme? Ich stehe nach 4h probieren, mittlerweile ziemlich auf dem Schlauch :/

Grüße und Danke schonmal
selig
 
#2
Wenn du kannst würde ich das Design der Datenbank ändern, denn es scheint Normalformen zu verletzen.

Was ist denn die Bedingung um die Werte der 2 Tabellen zueinander zu führen.
Gruß

Fluffy
 
#3
Guten Morgen,

was meinst du damit, dass die Normalformen verletzt werden?

Verknüpft werden die Tabellen über die Spalte all.

vereinfacht gesagt habe ich in Tabelle 1: Werte von 1-10
und in Tabelle2 Werte von 5-15.

Er soll mir also alles von 1-15 ausgeben, die Werte die in beiden Tabellen vorhanden sind aber anhand des Timestamps (den neueren Wert) ausgeben.

1-15, wäre die lösung die man mit Coalesce hinbekommen würde

Danke
 
#4
Hmm ich bin rausgeflogen und alles was ich getippt habe ist weg.
Ich halte es also deshalb hier mal kurz und knackig.
Hier kannst du nachlesen wiso die Normalformen verletzt sind.
Und hier wiso coalesce m.M. nach die Werte verdeckt und nicht wirklich 1-15 ausgibt.

mM nach wäre ein Union mit Sub-Selects und ausgetüftelten konditionals besser wenn du das Datenbankdesign nicht ändern kannst.
Wenn dann gibt uns mehr infos über die fachliche Bedeutung und wir könnten beim Design helfen.
Gruß

Fluffy
 
#5
Hey Fluffy,

in diesem Falle ist es keine Verletzung ;)
das würde jetzt aber den Rahmen sprengen, zu erklären warum das so sein muss - und nicht anders geht. (Im Prinzip sind es zwei seperate Anwendungen...)

Coalesce gibt meiner Meinung nach schon 1-15 aus -> coalesce(primär, sekundär). Sorgt dafür das immer ein Wert drin steht, im Falle das ein Wert in beiden Spalten vorhanden ist, wird dieser aus der ersten Spalte (hier primär) entnommen.

Bei mir sollte er aber nicht den ersten Wert nehmen, sondern den Wert in wessen Zeile das höhere Datum angesiedelt ist.

Und genau dabei hab ich Probleme :D und nein ich möchte nicht das Rad neu erfinden :D

Danke
 
#6
Ok.
ich habe hier gerade kein Setup um meinen Vorschlag zu testen.
Unter der Prämisse das du beim einer Deckung der Spalte "all" das aktuellere Datum ausgibst bedeutet dies, das bei einer nicht-Deckung Daten der tabelle 1 und 2 ausgegeben werden.
Das Problem bei Coalesce ist das man die ausgewählten Daten nicht gut auseinanderhalten kann und von den anderen abgrenzen kann.

Code:
(select all, wert, bemerkung, datum from t1 where all not in (select all from t2))
union
(select all, wert, bemerkung, datum from t2 where all not in (select all from t1))
union
(select all, wert, bemerkung, datum from t1 where all in(select all from t2))
 
#7
Guten Abend,

das UNION hat mir sehr geholfen,
habe jetzt folgende Lösung für zwei Tabellen die diese Struktur haben:

id, all, kategorie, wert, bemerkung, date

Code:
select * from (select * from 
((select * from tab1 where kategorie= '214')
union
(select * from tab2 where kategorie= '214')) AS tab
ORDER BY date desc) as tab2
GROUP BY all
Jetzt ist die Frage ob man das noch hübscher hinbekommt, also
durch das "union" hab ich ja alle Werte in der "virtuellen" Tabelle, was ja schonmal gut ist, allerdings gibt es ja jetzt die doppelten einträge (also spalte "all" kann jetzt einen Wert doppelt drin haben).
Diese könnte ich mit GROUP BY zusammen führen, jedoch soll er mir dann die Zeile mit dem größeren Datum und nicht nur das größte Datum der Gruppierung anzeigen...

^^Kannst du mir da folgen?

Code:
select * from 
((select * from tab1 where kategorie= '214')
union
(select * from tab2 where kategorie= '214')) AS tab
GROUP BY all
HAVING max(date) // Das klappt so aufjedenfall nicht
PS: Das "214" wird später durch php dynamisch in die Abfrage einfließen

THX schonmal bis hierhin
selig
 
#8
Hallo, ein
select * auf ein Group By all ist suboptimal, da der Inhalt der anderen Felder
nicht bestimmt ist, deswegen hast du auch probleme mit dem having.

Mein Beispiel vom letzten mal sollte mit einigen wenigen Anpassungen für dich genau das tun was du wolltest.
Gruß

Fluffy
 
#9
Grüß dich,

also wenn es um das äußerste "Select * from" geht, da werden nachher nur noch die benötigten Spalten abgefragt,...

Was meinst du damit, das der Inhalt anderer Felder nicht bestimmt ist?

Meine obere Lösung tut perfekt und genau das was sie tun sollte, ich frage mich nur ob das eleganter gelöst werden kann :D


Code:
(select all, wert, bemerkung, datum from t1 where all not in (select all from t2)) 
union 
(select all, wert, bemerkung, datum from t2 where all not in (select all from t1)) 
union 
(select all, wert, bemerkung, datum from t1 where all in(select all from t2))
Deine Abfrage nimmt zuerst alles aus t1 (wo "all" sich nicht mit t2 deckt)
Dann nimmst du alles aus t2 (wo "all" sich nicht mit t1 deckt)
und dann nimmst du noch alles was sich deckt,...

Dann hast du ja erstmal alles in einer Tabelle, aber das Datum zu überprüfen - fließt ja noch nicht mit ein.
Ich löse das ja indem ich sortiere und gruppiere.


vielleicht kann ich deinen Gedankengängen auch gerade nicht ganz folgen, ich teste aber nochmal :D

Danke :thumb_up:
 
Zuletzt bearbeitet:
#10
Mein oben angedachter Ansatz ist ja auch nicht vollständig, in Bezug auf die Bedigungen, und das Ordnen.
Es sollte nur einen Ansatz für die Problemlösung aufzeigen.

Bzgl. der Bestimmung der Inhalte der Spalten:
Ich kann schlecht erklären, deshalb lies es am besten hier mal nach.

Du benutzt wahrscheinlich MySQL.
MySQL ist was das angeht toleranter, aber produziert dahingehend trotzdem fehler.
Gruß

Fluffy
 
Oben