ich bin grade mit einem kleinen verschachtelten Mistding von Query beschäftigt.
Die soll folgendes machen:
tabelle:
name | id | original
teil a | 1 | 0
teil b | 2 | 1
teil c | 3 | 0
teil d | 4 | 1
jetzt sollen bei einer Suche nur die Teile ausgegeben werden, bei denen “original” auf 0 steht, wärs das gewesen würd ich nicht fragen. bei den teilen wo ein original angegeben ist soll aus der gruppe derer mit gleichem original immer das mit der höchsten id aussgegeben werden.
Tja so kanns gehen, während ich das Problem hier schirfitlich formuliert hab ist mir die Lösung eingefallen. Ich sollte das zukünftig immer machen, das aufschribeen und mal gucken ob ich nciht doch eine Lösung finde.
Da ich jetzt soviel getippt hab will ich das dann auch posten, mit Lösung.
Für Anmerkungen dankbar!
Gruß Crypi
SELECT
*
FROM
tabelle as a
WHERE
(
(
(
a.original=0
OR
a.original is null
)
AND
NOT EXISTS (
SELECT id
FROM
tabelle
WHERE
original=a.id
)
)
OR
a.id=
(
SELECT max(id)
FROM
tabelle
WHERE
original=a.original
)
)
ORDER BY upper(a.name);
ist ja 'ne sehr komplizierte Lösung die Dir dazu eingefallen ist. Das Beispiel des Code’s für die Tabelle ist da auch nicht ganz verständlich bzw. ausführlich. Vielleicht hilft dir so was einfaches weiter:
select *
from tabelle
where id in (
select max (id)
from tabelle
where original = 0
group by upper(name)
);
wäre es performance technisch nicht sinnvoller den subselect in den from-teil zu legen? dann würde das nur einmal ausgeführt werden. wenn du ihn in der where-klausel lässt ja bei jeden datensatz…
SELECT tabelle.*
FROM tabelle
, (
SELECT max(id) AS did
FROM tabelle
WHERE original = 0
GROUP BY upper(name)
) AS dummy
WHERE id = dummy.did;
sollte an sich auch gehen und von der performance her besser sein… auch wenn es sich hier nur um einen datensatz handelt sollte man imo immer für größere projekte planen
name | id | original
teil a | 1 | 0
teil b | 2 | 1
teil c | 3 | 0
teil d | 4 | 1
ausgegeben werden soll jetzt:
teil c (weil original = 0)
teil d (weil d die höchste id hat, unter den datensätzen die als original 1 haben)
a soll nicht ausgegeben werden, weil es ja datensätze gibt, die a (also id 1) als orginal verwenden.
b soll nicht ausgegeben werden, da d die häöhere id hat, bei gleichem original.
@ fristo mit deinem Beispiel bekomme ich nur die augegeben, wo original auf 0 steht.
nachdem ich gelesen habe, dass Du ein … bist, gebt ich Dir mal eine Hilfestellung.
Analysiere mal den Befehl
select max (id)
from tabelle
where original = 0
group by upper(name);
und überlege Dir (oder teste es aus), was der Befehl macht.
Nachdem Du den Befehl verstanden hast, wird es Dir nicht schwer fallen den Befehl umzustellen, zudem Du die Randbedingung zum Herausfiltern der 2 Datensätze schon richtig erkannt hast: Original. Aus dem obigen 4 Zeiler wird dann ein 3 Zeiler Einfacher geht es nicht mehr.
An den markierten Stellen ist die Logik nicht eindeutig.
Na ja, ich habe mal nachgedacht und hoffentlich ist es richtig:
DROP TABLE myTable]
Beide Versionen erbringen das gleiche Ergebnis. Die 2. Version wird wohl schneller sein. Ein Index auf id und original wird höchstwarscheinlich auch noch zur Erhöhung der Geschwindigkeit beitragen.
mfg
fristo
An den markierten Stellen ist die Logik nicht eindeutig.
[/quote]
Guten Morgen,
was ich sagen wollte ist, das ich mit Group by nicht weitergekommen bin, nicht das es hier nicht hilfreich wäre.
Das Problem der Logik versteh ich nicht.
Es gibt Datensätze, die id 1 als original verwenden, dass bedeutet, id 1 soll nicht mit ausgegeben werden.
was hier abgebildet werden soll ich quasi ein ein Verlauf, einzelne datensätze werden durch neuere ersätzt, hierbei soll aber nicht verloren gehen, für was die neuen datensätze als ersatz dienen sollen, also wird festgehalten was der ursprungsdatensatz war (original). da immer der aktuellste ausgegeben werden soll muss der mit der höchsten id ausgegeben werden unter denen die das gleiche original haben.
eine sache fehlt bei deinen querys noch, es werden jetzt auch die datensätze die 0 als orignal haben, also datensätze die keinen vorgänger besitzen, gruppiert und immer der mit der höchsten id ausgegeben, dass soll so nicht sein.
nochmal ein besipiel:
name | id | original
--------+----+----------
teil a | 1 | 0
teil b | 2 | 1
teil c | 3 | 0
teil d | 4 | 1
teil e | 5 | 0
teil f | 6 | 0
teil g | 7 | 6
gibt bei deinen aus:]
- es sollen alle ausgegeben werden, die als original 0 haben und deren id nicht als original verwendet wird (hier c und e)
- es soll jeweils der datensatz mit der höchsten id ausgegeben werden aus einer menge von datensätzen, die das gleiche original besitzen (hier d und g).
funktionieren tut das hier:
[code]
(select max (id) from myTable
where original<>0 group by original)
UNION
(SELECT id from mytable as a
where a.original=0
and
not exists
(select * from mytable where original=a.id)
);
ich hatte ja schon beim Nachdenken meine Zweifel Und der einzigste werd’ ich wohl auch nicht gewesen sein, der mit Deiner Beschreibung seine Probleme hatte.
Da muss ich Dir wiedersprechen! Wie Du hier geschrieben hast
ist Deine Analyse gut und Du hast es auch richtig gemacht, das Problem in kleine logische Einheiten zerlegt. Besser geht es nicht mehr. Und der von Dir entwickelte Code
Recht hast Du. Ich hatte ja auch schon mein Zeifel angemeldet. Du solltest aber auch Bedenken: Antworten basieren immer auf den Information die hier schriftlich mitgeteilt werden, und die sind nicht immer vollständig und eindeutig.
Das Aufgabe hast Du also selbst gut gelöst. Es geht doch.
ist mir auch nicht leicht gefallen das zu formulieren. naja jetzt ists ja irgendwie geglückt ]
Das Aufgabe hast Du also selbst gut gelöst. Es geht doch.
[/quote]