gregory666
Goto Top

Datensätze auf zwei Kriterien prüfen

Hallo,

wie bekomme ich am besten Datensätze aus einer Tabelle, welche 2 Kriterien entsprechen müssen.
Beispiel:
Tabelle Aufträge hat Felder "Ident" und "Artikel".
Darin u.a. Datensätze wie:
Ident=123456 Artikel=Hauptartikel
Ident=123456 Artikel=Nebenartikel 1
Ident=123456 Artikel=Nebenartikel 2

Die Nebenartikel sind optional.

Jetzt möchte ich nur Aufträge sehen, bei denen ein bestimmter Nebenartikel enthalten ist.
Das Problem: In den Ergebnissen muss der Hauptartikel angezeigt werden, und nur der.
Die Tabelle besitzt auf dem Feld "Ident" auch noch einen Join zu einer anderen Tabelle.

Ich habe das mit einer verschachtelten Abfrage hinbekommen, in der ich mir zunächst alle Aufträge mit dem gewünschten Nebenartikel suche,
aber das dauert bei 6 Ergebnissen schon ca. 4 Sekunden. Das liegt daran, das in der inneren Abfrage etwa 50000 Ergebnisse drin sind.
Das ist zu viel. Ich muss das irgendwie "schlanker" bekommen.

Ich kann den Auftragszeitraum begrenzen (das mache ich z.Z. in der äußeren Abfrage), jedoch liegen diese Infos (Datumsangaben) in der "gejointen" Tabelle. Ich wüßte jetzt nicht wie und ob ich in der inneren Abfrage das berücksichtigen kann.

Gruß, Andreas

Content-Key: 1212611426

Url: https://administrator.de/contentid/1212611426

Printed on: May 9, 2024 at 16:05 o'clock

Member: godlie
godlie Aug 31, 2021 at 05:39:28 (UTC)
Goto Top
Hallo,

wen fragst du denn da? deine Frau ? deinen Azubi? Excel, Access oder eine SQL Datenbank?
Member: Gregory666
Gregory666 Aug 31, 2021 at 05:44:15 (UTC)
Goto Top
Sorry, das habe ich vergessen anzugeben.

Es handelt sich um eine MS SQL-Datenbank.
Member: SachsenHessi
SachsenHessi Aug 31, 2021 at 05:54:04 (UTC)
Goto Top
Guten Morgen,
versuche es mal mit UNION.
Suche Hauptartikel und dann ein Union zum SELECT der Nebenartikel.
SH
Member: ukulele-7
ukulele-7 Aug 31, 2021 at 06:42:35 (UTC)
Goto Top
SELECT DISTINCT a1.* FROM Aufträge a1 INNER JOIN Aufträge a2 ON a1.Ident = a2.Ident AND a1.Artikel = 'Hauptartikel' AND a2.Artikel LIKE 'Nebenartikel%'  
Ich vermute mal deine Beispieldatensätze sind schlecht und es gibt noch ein anderes Kriterium das Nebenartikel als solche kenntlich macht und nicht eine Textspalte.

Das mit UNION kann eigentlich nicht sinnvoll sein.
Member: em-pie
em-pie Aug 31, 2021 at 06:57:50 (UTC)
Goto Top
Moin,

stimme hier @ukulele-7 zu: Das Beispiel ist Mist und UNION ist noch mehr Mist face-smile

Eine andere Möglichkweit wäre_
SELECT 
  artikel 
FROM 
  myAuftragPos 
WHERE 
  ident in (
    SELECT ident FROM myAuftragPos WHERE artikel = 'meinwunschartikel')  
  AND artikel = 'Hauptartikel'  

Besser wäre es, wenn man den Hauptartikel und die Nebenartikel eindeutig spezifizieren könnte. Denn was passiert, wenn dein Nebenartikel plötzlich ein Hauptartikel wird?
Vielleicht kann man über Produktgruppen gehen!?

Gruß
em-pie
Member: Gregory666
Gregory666 Aug 31, 2021 at 06:59:09 (UTC)
Goto Top
Zitat von @ukulele-7:

SELECT DISTINCT a1.* FROM Aufträge a1 INNER JOIN Aufträge a2 ON a1.Ident = a2.Ident AND a1.Artikel = 'Hauptartikel' AND a2.Artikel LIKE 'Nebenartikel%'  
Ich vermute mal deine Beispieldatensätze sind schlecht und es gibt noch ein anderes Kriterium das Nebenartikel als solche kenntlich macht und nicht eine Textspalte.

Das mit UNION kann eigentlich nicht sinnvoll sein.


Ich kann über die Zeilennummer erkennen ob es ein Nebenartikel ist, aber was bringt mir das wenn ich Aufträge mit speziell dem Artikel 'XYZ' suche. Die Artikelnummer ist doch nunmal ein Text.
Wenn ich die innere Abfrage mit allen Nebenartikeln aller Aufträge befülle, sind's doch noch viel mehr Datensätze als wenn ich nur die Artikel anziehe die ich eh suche.

Die Beispielabfrage ist interessant. Aus der Sichtweise habe ich das noch gar nicht gesehen.
Member: ukulele-7
ukulele-7 Aug 31, 2021 updated at 07:11:58 (UTC)
Goto Top
Du hast grundsätzlich drei Möglichkeiten da sinnvoll ran zu gehen.

1) Du baust was mit Subselect, so wie em-pie nur eben mit den Nebenartikeln. Ich glaube das hast du schon gemacht und es dauert vermutlich länger. Den Code hast du nicht gezeigt...
2) WHERE EXISTS ( Subselect ), ähnlich lange.
3) Oder ein Join, möglichst spezifisch so wie mein Ansatz. Könnte auch sehr viele Datensätze betreffen muss man ausprobieren, aber meist ist Join am schnellsten. Du joinst die Tabelle mit sich selbst, auf der einen Seite Hauptartikel, auf der anderen Nebenartikel die deine Kriterien erfüllen. Du nimmst nur die Spalten der Hauptartikel und filterst auf Dubletten, quick and maybe a bit dirty aber sollte es tuen.
Member: Gregory666
Gregory666 Aug 31, 2021 at 09:23:14 (UTC)
Goto Top
Zitat von @ukulele-7:

Du hast grundsätzlich drei Möglichkeiten da sinnvoll ran zu gehen.

1) Du baust was mit Subselect, so wie em-pie nur eben mit den Nebenartikeln. Ich glaube das hast du schon gemacht und es dauert vermutlich länger. Den Code hast du nicht gezeigt...
2) WHERE EXISTS ( Subselect ), ähnlich lange.
3) Oder ein Join, möglichst spezifisch so wie mein Ansatz. Könnte auch sehr viele Datensätze betreffen muss man ausprobieren, aber meist ist Join am schnellsten. Du joinst die Tabelle mit sich selbst, auf der einen Seite Hauptartikel, auf der anderen Nebenartikel die deine Kriterien erfüllen. Du nimmst nur die Spalten der Hauptartikel und filterst auf Dubletten, quick and maybe a bit dirty aber sollte es tuen.


Das ist korrekt. Die Version 1 hatte ich bisher.

Ich habe mich jetzt an dem self-join probiert.
Das Ergebnis ist erstaunlich gut. Soll heißen, verarbeitung ist zügig und zeigt an, was es soll.
Die Zeilennummer 10000 ist immer der "erste" Artikel und damit der Hauptartikel.
SELECT DISTINCT  TOP 100 a1.* FROM "Firma$Auftragsartikel" a1 INNER JOIN "Firma$Auftragsartikel" a2 ON a1."Ident" = a2."Ident"  where   
a1."Zeilennummer" = 10000 and a2."Artikel" LIKE '%MC.02.15%'  

Jetzt muss ich das irgendwie nochmal joinen mit der Tabelle "Firma$Auftragskopf". Das "Schlüsselfeld" ist wieder "Ident".
Denn letztendlich stehen viele relevante Felder in "Firma$Auftragskopf".
Also die Abfrage oben soll bestimmen welche Aufträge ich sehen möchte, aber es sollen noch zusätzliche Felder aus "Firma$Auftragskopf" angezogen werden.
Ich muss da erstmal die Gedanken sortieren wer da jetzt mit wem joinen muss.
Member: ukulele-7
Solution ukulele-7 Aug 31, 2021 at 09:35:08 (UTC)
Goto Top
Easy, einfach noch einen weiteren Join
SELECT DISTINCT a1.*,k.* FROM "Firma$Auftragsartikel" a1 INNER JOIN "Firma$Auftragsartikel" a2 ON a1."Ident" = a2."Ident"  where   
a1."Zeilennummer" = 10000 and a2."Artikel" LIKE '%MC.02.15%'  
LEFT JOIN "Firma$Auftragskopf" k  
ON a1."Ident" = k."Ident"  
TOP 100 ist nicht so gut wenn kein ORDER BY, ich denke mal das ist nur zum testen. Auch * sollte sauber aufgedröselt werden wenn der Code produktiv geht.
Member: Gregory666
Gregory666 Aug 31, 2021 updated at 11:25:06 (UTC)
Goto Top
Zitat von @ukulele-7:

Easy, einfach noch einen weiteren Join
SELECT DISTINCT a1.*,k.* FROM "Firma$Auftragsartikel" a1 INNER JOIN "Firma$Auftragsartikel" a2 ON a1."Ident" = a2."Ident"  where   
> a1."Zeilennummer" = 10000 and a2."Artikel" LIKE '%MC.02.15%'  
> LEFT JOIN "Firma$Auftragskopf" k  
> ON a1."Ident" = k."Ident"  
TOP 100 ist nicht so gut wenn kein ORDER BY, ich denke mal das ist nur zum testen. Auch * sollte sauber aufgedröselt werden wenn der Code produktiv geht.

Ja, das TOP 100 mache ich oft zum testen rein.
Die "where" Bedingung musste ich eine Zeile tiefer packen, habe sonst immer eine Fehlermeldung bekommen das ein Syntaxfehler in der Nähe von "Left" sei.
Nun funktioniert es.

Damit hast Du mir echt weiter geholfen, vielen Dank!