SQL-Befehle - SELECT verschiedene Tabellen

BigShot

Enthusiast
Thread Starter
Mitglied seit
06.02.2006
Beiträge
8.472
Hallo zusammen,

ich benötige Hilfe bei einer SQL-Abfrage:

Tabelle "Auftrag" enthält verschiedene Angaben zu Aufträgen, unter anderem das Feld "Art" (welches Angaben über die Vorgangsart, zum Beispiel Angebot / Rechnung) enthält und das Feld "Auftrag" welches eine einmalige ID ist.

Tabelle "Positionen" enthält alle Positionen jedes Auftrages, unter anderem gibt es das Feld "Ware2", welches eine Art Seriennummer enthält.



Ich muss nun folgendes auslesen:
Aus der Tabelle Positionen benötige ich den Wert des Feldes "Zusatztext2" zu "Ware2" = "123".
Soweit so gut, das funktioniert
Select Zusatztext2 From Positionen Where Ware2 ="123"

Nun benötige ich jedoch eine weitere Filterung, es soll nämlich nur die Informationen zurückgegeben werden, der jeweilige Auftrag (Tabelle Positionen Feld Auftrag) die Art "500" hat.

Nach folgenden Befehl werden zum Beispiel 5 Werte zurückgeliefert.
Select Auftrag From Positionen Where Ware2 ="123"

Autrag:
1
2
3
4
5

Jetzt müsste man also abfragen, welcher dieser 5 Aufträge in Tabelle "Auftrag" den Wert "500" im Feld "Art" hat. Falls es mehrere sind, das mit der größten Nummer (DESC 1).

ich hoffe das war verständlich.

Kann mir jemand helfen?
 
ich hoffe das war verständlich.
Geht so.

Ich nehme an, dass Tabelle "Positionen" auch das Feld "Auftrag" beinhaltet, wodurch Positionen zu einem Auftrag (N zu 1) zugeordnet werden können, richtig?

select positionen.zusatztext2
from positionen
inner
join auftrag on positionen.auftrag = auftrag.auftrag and auftrag.art = '500'
where positionen.ware2 = '123';



Jetzt müsste man also abfragen, welcher dieser 5 Aufträge in Tabelle "Auftrag" den Wert "500" im Feld "Art" hat. Falls es mehrere sind, das mit der größten Nummer (DESC 1).

Bin nicht, sicher, ob ich dich hier richtig verstehe. Was meinst du mit DESC 1?

select positionen.zusatztext2
from positionen
where positionen.ware2 = '123'
and positionen.auftrag in (
select max(auftrag.auftrag) from auftrag where auftrag.art='500' group by art
-- würde auftrag mit nr. 5 zurück leifern weil max. Wenn 1 gefordert ist, dann select min(...)
);


Wenn das nicht ist, was du brauchst, mach ein besseres Beispiel und beschreibe genauer.
Unbenannt.PNG
 
Zuletzt bearbeitet:
Geht so.

Ich nehme an, dass Tabelle "Positionen" auch das Feld "Auftrag" beinhaltet, wodurch Positionen zu einem Auftrag (N zu 1) zugeordnet werden können, richtig?

select positionen.zusatztext2
from positionen
inner
join auftrag on positionen.auftrag = auftrag.auftrag and auftrag.art = '500'
where positionen.ware2 = '123';
Super, das ist genau was ich brauche! Danke.

Bin nicht, sicher, ob ich dich hier richtig verstehe. Was meinst du mit DESC 1?

select positionen.zusatztext2
from positionen
where positionen.ware2 = '123'
and positionen.auftrag in (
select max(auftrag.auftrag) from auftrag where auftrag.art='500' group by art
-- würde auftrag mit nr. 5 zurück leifern weil max. Wenn 1 gefordert ist, dann select min(...)
);
Mit DESC 1 meinte ich absteigend und maximal 1. Also genau was du mit MAX machst.
Der Befehl funktioniert bei mir nur leider nicht.
Habe nun die obere Version abgeändert mit:


select positionen.Zusatztext2
from positionen
inner join auftrag on positionen.auftrag = auftrag.auftrag and auftrag.art = '500'
where positionen.ware2 = "22163" ORDER BY auftrag.auftrag DESC limit 1


Vielen Dank!!!
 
Zuletzt bearbeitet:
Und da sind wir bei den Eigenheiten von unterschiedlichen Datenbanken:
  • MSSQL: SELECT TOP(1) xx FROM yy ORDER BY xx DESC
  • ORACLE: SELECT * FROM (SELECT xx FROM yy ORDER BY xx DESC) t WHERE ROWNUM = 1
  • SQLite & Postgres: SELECT XX FROM YY ORDER BY XX DESC LIMIT 1
  • ...

Alternativ kann auch das ganze in eine andere Struktur gebracht werden, was mit dem GrouBy machbar ist, solange das auszugebende Feld numerisch ist:

SQL:
SELECT
    positionen.zusatztext2,
    MAX(positionen.auftrag) maxAuftrag -- Falls Indexe verwendet werden, kann auch das Ersetzen von positionen.auftrag durch auftrag.auftrag sinnvoll sein.
FROM positionen
INNER JOIN auftrag ON positionen.auftrag = auftrag.auftrag AND auftrag.art = '500'
WHERE positionen.ware2 = "22163"
GROUP BY  positionen.zusatztext2

Fals es wirklich eine entsprechende Sonderfunktion sein soll, kann auf fast jedem SQL-System auch mit Cursorn und Schleifen gearbeitet werden ...
 
Zuletzt bearbeitet:
Und da sind wir bei den Eigenheiten von unterschiedlichen Datenbanken:
  • MSSQL: SELECT TOP(1) xx FROM yy ORDER BY xx DESC
  • ORACLE: SELECT * FROM (SELECT xx FROM yy ORDER BY xx DESC) t WHERE ROWNUM = 1
  • SQLite & Postgres: SELECT XX FROM YY ORDER BY XX DESC LIMIT 1
  • ...
Nein, eigentlich nicht. Alle deine Beispiele sind eine umständliche Schreibweise um das Gleiche zu erreichen, wass die MAX Funktion erledigt. Und MAX ist ANSI-SQL, sollte somit in jeder relationalen Datenbank implementiert sein.

Da @BigShot den Fehler nicht genannt hat, können wir nur raten, was schief gegangen ist. Es könnte auch einfach nur ein Type Mismatch gewesen sein, wer weiß. Ich habe ja nur SQLite gewählt um schnell an ein Beispiel zu kommen und wollte jetzt nicht unbedingt remote auf die Oracle oder Postgres DB bei der Arbeit.
 
Zuletzt bearbeitet:
@Murazor das kommt immer darauf an, was gemacht werden soll. Hier mal ein paar gegenüberstellungen aus einem MSSQL Server:

SQL:
-- Declare
DECLARE @auftrag TABLE (auftrag int, art int);
DECLARE @positionen TABLE (auftrag int, ware2 varchar(128), zusatztext2 varchar(512));

-- Seed
insert into @auftrag
select 1, 200 UNION select 2, 200 UNION select 3, 500 UNION SELECT 4, 200 UNION select 5, 200;

insert into @positionen
select auftrag, '123', 'Bla234' from @auftrag;

--> Query3
SELECT
    positionen.zusatztext2,
    MAX(positionen.auftrag) maxAuftrag
FROM @positionen positionen
INNER JOIN @auftrag auftrag ON positionen.auftrag = auftrag.auftrag AND auftrag.art = '200'
GROUP BY  positionen.zusatztext2;

--> Query4
SELECT TOP(1)
    positionen.zusatztext2,
    auftrag.auftrag maxAuftrag
FROM @positionen positionen
INNER JOIN @auftrag auftrag ON positionen.auftrag = auftrag.auftrag AND auftrag.art = '200'
ORDER BY auftrag.auftrag DESC;

--> Query5
SELECT
    auftrag.auftrag maxAuftrag,
    MAX(positionen.zusatztext2) maxAuftrag
FROM @positionen positionen
INNER JOIN @auftrag auftrag ON positionen.auftrag = auftrag.auftrag AND auftrag.art = '200'
GROUP BY  auftrag.auftrag;

Hier die dazugehörigen Ausführungspläne:
1629184923294.png


Die Performance der Abfragen (ohne Optimierungen:
AbfrageOperation CostPlan Size
Query30,017924KB
Query40,035224KB
Query50,035232KB

Daher hast du Recht, dass bei einer einfachen Abfrage mit nur einer Aggregatsfunktion auf ein numerischen Typ das Min/Max immer schneller ist. Aber wenn die Abfragen komplexer werden, oder er Abfragetyp nicht mehr Numerisch ist, kann es bedeuten Performanter sein, ein Limit/Top o.Ä. zu verwenden. Dieses hat aber nicht mehr wirklich was mit der eigentlichen Frage zu tun ;)

Ich hoffe dennoch, dass wir helfen konnten
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh