[SQL] Select-Anweisung

ottscho

Well-known member
24 April 2006
188
3
Hallo zusammen,
ich habe zwei Tabellen. Erste Tabelle mit Stammdaten von Drucker und zweite Tabelle mit Aktivitäten/Verlauf. Nund steht in der Zweiten Tabelle immer die DruckerID, verschiedene Felder und der Standort. Nun möchte ich alle Drucker selektieren, welche als Standort bei uns eingetragen sind.
das Problem ist, dass es so gespeicher wird:

ID / Drucker_Aktiv_ID / Standort / Aktivität
1 / 1 / IDENTA / Drucker getestet und Firmware upgedatet
2 / 1 / KUNDE / Drucker an Kunde verschickt
3 / 1 / IDENTA / Kund reklamiert, Druckkopfdefekt
4 / 1 / Evolis / Drucker an Hersteller geschickt

wenn ich es nun so mache
Code:
SELECT * FROM tbl_drucker INNER JOIN tbl_aktiv
ON (tbl_drucker.Drucker_ID = tbl_aktiv.drucker_aktiv_id) WHERE tbl_aktiv.standort = "IDENTA"

erhalte ich ja jeden Datensatz, weil alle Drucker erst bei uns getestet werden, bevor sie rausgehen. Nun soll sich das WHERE = IDENTA nur auf den neusten Datensatz mit der höchsten ID beziehen.

Ich hoffe ihr versteht was ich meine ;)

Danke
Grüße ottscho
 
Wo ist das Problem da noch ein ORDER BY hinten dranzuhängen ?

Oder hab ich was falsch verstanden ?

Ansonsten poste mal bitte Daten und dein erwartetes Ergebnis.
 
das Problem ist, dass jeder Stammdatensatz eine Aktivität mit dem Standort IDENTA hat, weil dies ja der erste Anlaufpunkt ist, bevor es zum Kunden geht.

Beispiel:

tbl_drucker
Code:
Drucker_ID  Kunden_ID  Modell  Seriennummer  Druckkopfseriennummer  MAG  Kontaktchip  RFID_Legic  
101 02487 Evolis Pebble 3 P54634101 312-5X-00505-B 0 0 0 
102 03704 Evolis Pebble 3 P53329217 327-54-00324-B 0 0 0 
103 02487 Evolis Pebble 3 P54634085 305-5X-00428-B 0 0 0

so, nun nehmen wir als Beispiel den Drucker mit der ID 101.
wenn man sich die dazu gehörigen Daten in der tbl_aktiv anschauen:
Code:
aktiv_id  drucker_aktiv_id  datum  aktivität  standort  Original_Karton  Treiber  USB_Kabel  Parallel_Kabel  Netzteil  Farbband  Schwarzband  Transferband  
16 101 2005-11-24 Drucker geprüft IDENTA 1 0 0 0 0 0 0 0
17 101 2005-11-24 an Kunde versendet Kunde 1 0 0 0 0 0 0 0

zu den Drucker gehören nun zwei Datensätze. Der erste, dass er geprüft worden ist und der zweite, dass er an Kunden geschickt worden ist.
Frage ich nun mit meiner Select-Anweisung ab, so erhalte ich den ersten Datensatz, weil dort Standort IDENTA steht, aber dies Interessiert mich ja nicht, weil der drucker versendet worden ist.

versteht du mein Problem? Ist etwas schwierig zu erklären.
 
Dann könntest du doch einfach nach aktiv_id absteigend sortieren (bzw max(aktiv_id)) und LIMIT 0,1 setzen.

Ich denke ich habe es jetzt verstanden :)
 
oder du gibts bei aktivität immer den selben string an und lässt den datensatz mit diesem wert (string) bei aktivität weg (aktivität not "test").

stumpi

p.s.: noch besser: ID > 1, damit fällt der erste datensatz weg;)
 
@Johnson
danke, soweit habe ich leider auch schon gedacht :) dies fuktioniert auch, wenn ich nur den Status von einem Drucker sehen möchte. Aber wie mache ich es, wenn ich sehen möchte welche Drucker alle im Moment hier bei uns in der Firma sind?

SELECT * FROM tbl_drucker INNER JOIN tbl_aktiv
ON (tbl_drucker.Drucker_ID = tbl_aktiv.drucker_aktiv_id) WHERE tbl_aktiv.standort = "IDENTA"

Wenn ich doch hier Limit 1 mache, erhalte ich ja nur einen Datensatz! Irgednwie stehe ich total auf dem Schlauch.
 
p.s.: noch besser: ID > 1, damit fällt der erste datensatz weg;)

und wie mache ich es, wenn der verlauf so war, bei uns getestet, dann zum kunden geschickt, gerät defekt, bei uns druckkopf getauscht, gerät wieder zum kunden geschickt ;)

dann fählt zwar der mit der ID1 weg, aber ID3 hat nun auch den Eintrag Standort IDENTA. Und wir daruch wieder als verfügbar selektiert, obwohl er nicht im Haus ist.
 
Aber wie mache ich es, wenn ich sehen möchte welche Drucker alle im Moment hier bei uns in der Firma sind?
Wenn ich doch hier Limit 1 mache, erhalte ich ja nur einen Datensatz! Irgednwie stehe ich total auf dem Schlauch.

Bei obiger Query einfach kein Limit setzen, z.B.
Code:
SELECT * FROM tbl_drucker INNER JOIN tbl_aktiv
ON (tbl_drucker.Drucker_ID = tbl_aktiv.drucker_aktiv_id) WHERE tbl_aktiv.standort IN("INDENTA", ...)

edit: Bei obigem Fall geht das allerdings auch nicht. Hier sollte eventuell DISTINCT / GROUP BY (bin mir da nicht so sicher) weiterhelfen.

Ich würde mir allerdings über den Sinn der DB-Struktur Gedanken machen und eventuell Status-Codes zum einfachen Auslesen einführen. Die aktivität kann ja - wie ich es von hier beurteilen kann - redundant sein, was auch für eine Neustrukturierung der DB spricht.
 
Bei obiger Query einfach kein Limit setzen, z.B.
Ich würde mir allerdings über den Sinn der DB-Struktur Gedanken machen und eventuell Status-Codes zum einfachen Auslesen einführen. Die aktivität kann ja - wie ich es von hier beurteilen kann - redundant sein, was auch für eine Neustrukturierung der DB spricht.

Die Datenbank besteht aber schon eine weile, und sollte nicht unbedingt geändert werden. Am Besten wäre eine Lösung mit der bestehenden DB.
 
ich könnte es noch mit PHP in einer Schleife mache, dies ist aber natürlich auch nicht die optimale Lösung
 
Die Datenbank besteht aber schon eine weile, und sollte nicht unbedingt geändert werden. Am Besten wäre eine Lösung mit der bestehenden DB.

Hab hier mal rumprobiert
Code:
SELECT DISTINCT drucker.id FROM drucker
INNER JOIN drucker_aktiv
ON drucker_aktiv.drucker_id = drucker.id AND drucker_aktiv.status != 'leer' ORDER BY datum DESC

Allerdings bin ich nicht sicher wo die ORDER BY-Klausel hier sortiert, man sollte das ganze erstmal gründlich überprüfen und im Manual nachschauen - hab jetzt Mittagsschule ;)

Gruß
 
Oioioiii ... sorry, wenn ich das sagen muss, aber deine Datenbankstruktur ist für diesen Zweck nicht gerade optimal. Wenn du einerseits den Verlauf und andererseits den aktuellen Zustand kennen willst, dann müsste man es doch etwas anders aufbauen.

Ansonsten wäre das einfachste ein zusätzliches Feld anzuhängen und den letzten aktuellsten Eintrag des Druckers als solchen zu kennzeichnen.

Oder du arbeitest mit GROUP BY und HAVING.
Versuch es mal mit GROUP BY drucker_id HAVING MAX(id) = id ... also im Prinzip nach dem Drucker gruppieren und davon die höchste ID aus allen Zeilen zu diesem Drucker rauspicken. Bin grad in Eile, kann sein, daß die obige Klausel nicht gaaanz richtig ist, aber probier es mal aus, das Prinzip sollte das gewünschte sein :)

Wenn du kein Glück damit hast, guck ich mal morgen rein und poste das richtige ;)
 
@SpecialsGuy

habe die Anfrage nun so:
Code:
SELECT * 
FROM tbl_aktiv
GROUP BY drucker_aktiv_id
HAVING MAX( aktiv_id )

nun wird alles nach drucker_aktiv_id gruppiert, aber leider klappt es nicht richtig mit dem HAVING MAX ( aktiv_id ). Hier bin ich der Meinung, dass er einfach einen Datensatz nimmt.

kannst du es dir bitte nochmal anschauen?

Vielen Dank
MFG ottscho
 
eigenltlich müsste es ja so gehen:
Code:
SELECT * 
FROM `tbl_aktiv` 
GROUP BY `drucker_aktiv_id` 
HAVING aktiv_id = MAX( `aktiv_id` ) 
ORDER BY `drucker_aktiv_id` ASC 
LIMIT 0 , 30

aber jetzt erhalte ich nicht alle Datensätze. er lässt einfach welche aus :-/
 
ich glaube eine kleinigkeit fehlt noch beim having:
Code:
SELECT * 
FROM `tbl_aktiv` 
GROUP BY `drucker_aktiv_id` 
HAVING aktiv_id = MAX( select max(aktiv_id) from tbl_aktiv where drucker_aktiv_id ) 
ORDER BY `drucker_aktiv_id` ASC 
LIMIT 0 , 30

so sollte es gehen, habe ich aber auch nur "aus der kalten" geschrieben.

stumpi
 
ich glaube eine kleinigkeit fehlt noch beim having:
Code:
SELECT * 
FROM `tbl_aktiv` 
GROUP BY `drucker_aktiv_id` 
HAVING aktiv_id = MAX( select max(aktiv_id) from tbl_aktiv where drucker_aktiv_id ) 
ORDER BY `drucker_aktiv_id` ASC 
LIMIT 0 , 30

so sollte es gehen, habe ich aber auch nur "aus der kalten" geschrieben.

stumpi

Code:
HAVING aktiv_id = MAX( select max(aktiv_id) from tbl_aktiv where drucker_aktiv_id )

hier fehlt noch noch was? WHERE drucker_aktiv_id = ?
wie meinst du es?
 
ich habe da wirklich was vergessen, sorry:
Code:
SELECT * 
FROM tbl_aktiv as tbla
GROUP BY tbla.drucker_aktiv_id 
having aktiv_id = (select max(aktiv_id) from tbl_aktiv as tblb where tblb.drucker_aktiv_id=tbla.drucker_aktiv_id)
ORDER BY tbla.drucker_aktiv_id ASC 
LIMIT 0 , 30

ist aber wieder nur aus der kalten geschrieben.

stumpi
 
ich habe da wirklich was vergessen, sorry:
Code:
SELECT * 
FROM tbl_aktiv as tbla
GROUP BY tbla.drucker_aktiv_id 
having aktiv_id = (select max(aktiv_id) from tbl_aktiv as tblb where tblb.drucker_aktiv_id=tbla.drucker_aktiv_id)
ORDER BY tbla.drucker_aktiv_id ASC 
LIMIT 0 , 30

ist aber wieder nur aus der kalten geschrieben.

stumpi

geht leider auch nicht. ich erhalte zwar kein fehler. aber er lässt mir einfach ein paar datensätze aus.
siehe bild.



Die zweite nr müsste normalerweise fortlaufend sein (drucker_aktiv_id). aber aus irgendwelchen gründen fehlen ab und zu datensätze dazwischen!