Neuigkeiten:

still alive...

Hauptmenü

Kifflige Abfrage über 2 Tabellen

Begonnen von smile1, 08. November 2009, 14:43:13

Vorheriges Thema - Nächstes Thema

smile1

Hi,
ich suche eine Möglichkeit eine Tabelle(a) mit hilfe einer anderen Tabelle(b) abzufragen und dabei nur einen bestimmten Teil von Tabelle(a) zurückzugeben. Genau sieht das so aus:

Tabelle(a):
logtable
ID              PARTID      DATE_STAMP   (und noch ein paar andere Spalten, die aber keine Rolle spielen)
Hier werden alle Vorgänge für die jeweiligen Teile (logtable.PARTID = partlist.ID) hinterlegt!

Tabelle(b):
partlist
ID     NAME   (etc.)
Hier stehen alle Teile drin (sind zur Zeit ca. 260)!

Ich möchte nun jeweils den letzten Eintrag (DATE_STAMP) in (logtable) von jedem Teil aus (partlist) ausgeben. Also bei der Rückgabe dürfte unter (PARTID) kein Eintrag doppelt vorkommen und es muss jeweils der letzte Eintrag von diesem Teil sein.
Habs schon mit GROUP BY etc. versucht, aber ich komm auf keinen grünen Zweig. Vielleicht weiß ja jemand einen Rat!?

Powie

Du musst einen Join machen, und die Spalte DATE_STAMP nicht so mit nehmen wie sie ist, sondern nur die spalten holen mit max(date_stamp). Wie genau das jetzt aussieht kann ich dir auf Anhieb nicht sagen...
Teste mal:
Select p.name, max(l.date_stamp)  as lastlog
From partlist p
Left Join logtable l on l.partid=p.id
Group By p.id
Order By p.id

smile1

Danke erstmal, nur leider klappt das nicht.
Zumindestens ist mir eingefallen das ich die zweite Tabelle eigentlich nicht brauch.
Mein derzeitiger Ansatz sieht so aus:
SELECT * FROM logtable
GROUP BY partid
Das Zeigt mir zumindestens immer nur einen Eintrag von jedem Teil, jedoch nicht das letzte. Man müsste also vorher noch nach ID Absteigend sortieren (DATE_STAMP is sowieso nicht optimal dafür, aber das hat andere Gründe). Habe schon versucht mit HAVING max(ID) die richtigen Zeilen zu erhalten aber da kommt genau das gleiche wie ohne HAVING raus.

Powie

dann so:
SELECT partid, max(date_stamp) FROM logtable
GROUP BY partid

smile1

Ne, dann gibt er mir zwar die letzte ID bzw. DATE_STAMP zurück, aber an der Auswahl der Zeile(n) ändert sich nix.
Das Problem ist das ich bei der Auswertung noch auf einen Wert einer anderen Spalte (hab ich nicht mit aufgelistet) zurückgreifen muss, und da brauch ich natürlich den letzten Eintrag und nicht den ersten oder zweiten.

smile1

Ajso ich habs jetzt. Mit Hilfe aus einem anderen Forum.
Und zwar muss es so aussehen:

SELECT * FROM logtable
WHERE ID IN (SELECT max(id) FROM logtable GROUP BY partid)

Powie


raiser

Hmmm,lecker
Subselcts.....
Sehr performant, bei einer großen Anzahl an Tupel.

Wissen ist das einzige Gut, dass sich vermehrt, wenn man es teilt! (Marie von Ebner-Eschenbach)




Irren ist menschlich!




Wer andern eine Grube gräbt,


sollte darüber nachdenken,


ob sie tief genug ist!!!!




Kameradschaft ist, wenn der


Kamerad schafft !!!!


lit-web


Original von Raiser Hmmm,lecker
Subselcts.....
Sehr performant, bei einer großen Anzahl an Tupel.
[/quote]
Und nun lass mal noch dazu kommen das es am Ende ein sehr schlechtes DB Design dahinter steht, da ist bei großen Datenmengen und vielen Klicks wo auf einmal etliche Querys ausgelöst werden ein Zusamenbruch vorprogrammiert.
Also Subselects sollte man nur anwenden wenn es unbedingt nötig ist und gar nicht anders geht.

Taugenichtse die was haben,haben was gegen Habenichtse die was taugen!!!!


k00ni

Kann es sein, dass man mit dem geposteten Query vom smile1 eh nur einen Datensatz bekommt? Das bringt doch nüscht ...

Powie

Der gepostete Query ist in der Tat sehr LOL: und würde er funktionieren dann ist er schlecht durchdacht. In der Regel ist die grösste ID zwar die letzte, das muss aber nicht zu 100% so sein! Welchen sinn das Thema überhaupt hatte ist mir ein Regel.
Zu Subselsects: Es ist vollkommen Quatsch Subselects schlecht zu reden. Mit jahrelanger Erfahrung mit DB2 muss ich sagen habe ich Subselects lieben gelernt, gerade wegen der Performance. Bei vielen optimierten Abfragen haben wir gerade durch Subselects enorme Steigerungen der Performance erzielt.
Bei mysql werden sie nur gern verteufelt weil sie in den alten Versionen nicht möglich waren. Zudem ist ein Join ein Join und ein Subselect etwqas ganz anderes mit einem ganz anderen Hintergrund.

smile1

Also erstmal, danke für das große Interesse. /uploads/emoticons/icon_e_wink.gif.c059000ae48ff64afa53be0962c021f2.gif\" alt=\":wink:\" />
Zum Thema:
- vorerst greife ich auf ne mysql datenbank zu, aber letztendlich wird das auf ner Oracle DB laufen!
- Quatsch ist diese Query ganz und gar nicht, denn sie bewirkt genau das was ich brauche. Wenn ich es über PHP gelöst hätte hätte ich bei jedem Seitenaufruf ne Schleife mit ca. 260 DB Querys durchlaufen müssen, und das ist ganz gewiss sehr viel langsamer!
- Das Query gibt nicht nur ein Ergebniss wieder, es gibt pro Bauteil (partid) das letzte Vorkommen wieder
- Und in meinem Fall ist die höchste ID von jedem Bauteil mit Sicherheit auch der letzte Eintrag!

raiser

@powie.
ich verteufel die Subselects nicht. im Gegenteil. Ich mag sie.
Nur leider ist es immer noch bei MySQL so, dass, wenn man einen Subselect auslöst, das gesamte kartesische Produkt vor dem (ON) steht. Man hat deshalb, auch wenn nur kaum merkbar    [.. aja und jetz kommen wieder die ORCLEer.. per Optimierer..]  trotzdem einen Nachteil.
Versucht doch bei MySQL die Subquerys so dünn wie möglich zu halten. Nehmt tempTables und baut euch euer eignes (mit JOIN gebautes) kartesiche /uploads/emoticons/icon_e_smile.gif.4a0acefcb917340d2c82e5239c009e6e.gif\" alt=\":)\" /> Produkt. Ist alle mal schneller, als mit der vollen Kanone (IN), darufballern zu lassen.
 
lG Henrik

Wissen ist das einzige Gut, dass sich vermehrt, wenn man es teilt! (Marie von Ebner-Eschenbach)




Irren ist menschlich!




Wer andern eine Grube gräbt,


sollte darüber nachdenken,


ob sie tief genug ist!!!!




Kameradschaft ist, wenn der


Kamerad schafft !!!!


Powie

Ja das stimmt, aus Erfahrung: TEMP Tables sind noch viel schneller.
Aber nicht immer, es ist immer eine Frage wieviele Daten dahinter stehen die durchsucht werden müssen. Das kann man aber gut probieren, indem man einfach mal die benötigten Daten die man in den Joins haben möchte vorher alleine mal selektiert und schaut wieviel das ist. Ich hab es oft einfach verglichen wo die Daten schneller geliefert werden können.

hello007

Naja Subselect haben keine chance gegen temptables.
Bei kleineren abfragen macht sich kein Unterschied bemerkbar, bei größeren hochwertigen datensätze wirste mit nem subselect alt aussehen.
Angenommen du hast eine große abfrage mit 3selects, so sql muss jedesmal für jeden eintrag die select neu aufrufen.Bei Join wird einfach nur eine temps angelegt und verglichen.
SubSelect sind nur gut um SQL zu erlernen(meine Meinung) aber nicht um lasthaltige Abfragen zu erstellen.
Wenn du lebensmittel einkaufst, tutst ja auch nicht jedes lebensmittel extra bezahlen und extra ins auto legen, oder doch?

alias theCrack




Oldmember of Kryptocrew


all your base are belong to us