Distinct Abfrage aber ohne Distinct
Hallo,
ich bekomme mit einer größeren Abfrage aus der Datenbank folgende Daten:
Artikel Maschine Material Datum
1----------A--------------------C----------1.1.2017
2----------A--------------------C----------1.2.2017
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------F----------1.1.2017
Nun möchte ich, dass die Ergebnismenge im Feld Material eindeutig ist.
Distinct kann ich nicht nehmen, da ich Artikel und Maschine aus Daten brauche und deshalb die Datensätze nicht herausgefiltert werden würden.
Select TOP 1 als Unterabfrage kann ich auch nicht nehmen, da ich wie gesagt alle Daten brauche und mehrere Unterabfragen zu heftig wären.
Im o.g. Fall will ich den 1. Datensatz rausschmeißen, damit das Material C nur einmal vorkommt. Diese Entscheidung soll auf Grund des Datum gefällt werden. Die Einträge bei Artikel 2 sind neuer.
Hat jemand eine Idee, wie ich das machen kann?
Ich stehe auf dem Schlauch.
Es würde evt. auch reichen, wenn die Bedingung mit dem Datum ignoriert wird. Ich brauche halt nur jedes Material einmal, mit irgendwelchen Infos unter Artikel und Maschine.
Gruß Mäxx
P.S. Das Ganze bitte nicht als gespeicherte Prozedur, wenn es geht.
ich bekomme mit einer größeren Abfrage aus der Datenbank folgende Daten:
Artikel Maschine Material Datum
1----------A--------------------C----------1.1.2017
2----------A--------------------C----------1.2.2017
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------F----------1.1.2017
Nun möchte ich, dass die Ergebnismenge im Feld Material eindeutig ist.
Distinct kann ich nicht nehmen, da ich Artikel und Maschine aus Daten brauche und deshalb die Datensätze nicht herausgefiltert werden würden.
Select TOP 1 als Unterabfrage kann ich auch nicht nehmen, da ich wie gesagt alle Daten brauche und mehrere Unterabfragen zu heftig wären.
Im o.g. Fall will ich den 1. Datensatz rausschmeißen, damit das Material C nur einmal vorkommt. Diese Entscheidung soll auf Grund des Datum gefällt werden. Die Einträge bei Artikel 2 sind neuer.
Hat jemand eine Idee, wie ich das machen kann?
Ich stehe auf dem Schlauch.
Es würde evt. auch reichen, wenn die Bedingung mit dem Datum ignoriert wird. Ich brauche halt nur jedes Material einmal, mit irgendwelchen Infos unter Artikel und Maschine.
Gruß Mäxx
P.S. Das Ganze bitte nicht als gespeicherte Prozedur, wenn es geht.
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 339420
Url: https://administrator.de/forum/distinct-abfrage-aber-ohne-distinct-339420.html
Ausgedruckt am: 25.12.2024 um 02:12 Uhr
11 Kommentare
Neuester Kommentar
Moin,
mal nur vom logischen Ansatz her:
wie wäre es mit einem Join auf die selbe Tabelle:
die zu joinende Tabelle hat eine Group by Clause:
Der Code ist ungetestet, müsste aber ein brauchbares Ergebnis liefern, sofern ich jetzt nicht gerade einen Knoten im Kopf habe...
€dit: noch eine kurze Erklärung/ Anmerkung zum obigen Code. Ich gehe davon aus, dass wenn es eine folgende Kombination gäbe
1----------A--------------------C----------1.1.2017
2----------A--------------------C----------1.2.2017
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------E----------1.1.2017
6----------A--------------------F----------1.1.2017
du auch die Kombination B-E und A-E sehen möchtest!?
Wenn nicht, schmeiße aus dem Group by und dem dazugehörigen Select die Maschine raus, dann wird nur nach dem Material und dem Datum "gefiltert"
Gruß
em-pie
mal nur vom logischen Ansatz her:
wie wäre es mit einem Join auf die selbe Tabelle:
die zu joinende Tabelle hat eine Group by Clause:
SELECT
A.Artikel
, A.Material
, A.Maschine
, A.Datum
FROM
Tbl as A
INNER JOIN
(SELECT Material, Maschine, MAX(Datum)
FROM Tbl
GROUP BY Material, Maschine, Datum) as B on
A.Maschine = B.Maschine AND A.Material=B.Material AND A.Datum = B.Datum
Der Code ist ungetestet, müsste aber ein brauchbares Ergebnis liefern, sofern ich jetzt nicht gerade einen Knoten im Kopf habe...
€dit: noch eine kurze Erklärung/ Anmerkung zum obigen Code. Ich gehe davon aus, dass wenn es eine folgende Kombination gäbe
1----------A--------------------C----------1.1.2017
2----------A--------------------C----------1.2.2017
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------E----------1.1.2017
6----------A--------------------F----------1.1.2017
du auch die Kombination B-E und A-E sehen möchtest!?
Wenn nicht, schmeiße aus dem Group by und dem dazugehörigen Select die Maschine raus, dann wird nur nach dem Material und dem Datum "gefiltert"
Gruß
em-pie
So geht es auch ^^
was mich allerdings noch irgendwie interessiert:
Wie meinst du das?
Ich habe bisher schon viel mit Views gearbeitet/ gebastelt/ vermurkst.
Eine View verhält sich mit reinen Select-Befehlen wie eine "normale" Tabelle. Soll heißen:
Eine View lässt sich (mit sich selbst) Joinen, als SubSelect verwenden oder als View innerhalb einer View verwenden, etc....
Was jedoch beim Erstellen von Views nicht geht (und eigentlich auch keinen Sinn ergibt), sind statements wie Order by.
z.B.
Das fürht (zumindest beim MS SQL-Server) immer zu abbrüchen/ Fehlermeldungen...
Gruß
em-pie
was mich allerdings noch irgendwie interessiert:
Dafür müsste ich aber die ursprüngliche Abfrage als Temp-Tabelle haben, was in einer Sicht nicht geht.
Wie meinst du das?
Ich habe bisher schon viel mit Views gearbeitet/ gebastelt/ vermurkst.
Eine View verhält sich mit reinen Select-Befehlen wie eine "normale" Tabelle. Soll heißen:
Eine View lässt sich (mit sich selbst) Joinen, als SubSelect verwenden oder als View innerhalb einer View verwenden, etc....
Was jedoch beim Erstellen von Views nicht geht (und eigentlich auch keinen Sinn ergibt), sind statements wie Order by.
z.B.
CREATE OR REPLACE VIEW "myView" AS
SELECT Field1, Field2, Field3
FROM myTable
ORDER BY Field1
Gruß
em-pie
Moin Maexx77,
offen gestanden möchte ich diesen Beitrag nicht in diesem Zustand hier als "Gelöst" stehen lassen.
em-pie's Skizze würde - wenn sie denn berichtigt wäre und das tut, was es tun sollte - nicht das gewünschte Ergebnis bringen, wenn mehrere Artikel mit dem selben Material vorliegen.
Dein Kommentar "mit First_value klappt es" .... mag ja sein, aber auch da bringt doch "First_VALUE(Datum) OVER().."auch nur dasselbe wie ein Max(datum) OVER(..) ".
Vorteil wäre natürlich, dass du kein GROUP BY auf die Gesamt-Abfrage brauchst, also kein " SELECT ...., max(Datum) ...GROUP BY Artikel, Maschine, Material".
Kannst du bitte mal deine FIRST_VAULE() im ganzen Satz zeigen, damit es für nachfolgende Ratsuchende hilfreich wird?
Grüße
Biber
offen gestanden möchte ich diesen Beitrag nicht in diesem Zustand hier als "Gelöst" stehen lassen.
em-pie's Skizze würde - wenn sie denn berichtigt wäre und das tut, was es tun sollte - nicht das gewünschte Ergebnis bringen, wenn mehrere Artikel mit dem selben Material vorliegen.
Dein Kommentar "mit First_value klappt es" .... mag ja sein, aber auch da bringt doch "First_VALUE(Datum) OVER().."auch nur dasselbe wie ein Max(datum) OVER(..) ".
Vorteil wäre natürlich, dass du kein GROUP BY auf die Gesamt-Abfrage brauchst, also kein " SELECT ...., max(Datum) ...GROUP BY Artikel, Maschine, Material".
Kannst du bitte mal deine FIRST_VAULE() im ganzen Satz zeigen, damit es für nachfolgende Ratsuchende hilfreich wird?
Grüße
Biber
Moin Maexx77,
danke für deine Lösung.
Aber auch mit der habe ich ein bzw. zwei Verständnisprobleme.
Erstes Verständnisproblem:
em-pie hat doch in seinem konstruierten Beispiel eine der Sollbruchstellen aufgezeigt.
1----------A--------------------C----------1.1.2017
2----------A--------------------C----------1.2.2017
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------E----------1.1.2017
6----------A--------------------F----------1.1.2017
In diesen Beispiel würde doch das Material "E" auf zwei Maschinen (A und B) verwendet und für zwei unterschiedliche Artikel (4 und 5).
Dein SELECT würde daraus machen
2----------A--------------------C -> hier ist richtigerweise der Satz 1/Artikel 1ausgefiltert
3----------B--------------------D
4----------B--------------------E --> Hier würde als "Artikel" unvorhersagbar 4 oder 5 herauskommen als FIRST_VALUE()
4----------A--------------------E --> Hier würde als "Artikel" unvorhersagbar 4 oder 5 herauskommen als FIRST_VALUE()
6----------A--------------------F
Es ist somit mindestens eine ausgegebene Zuordnung Material-Maschine-Artikel falsch - im der Realität gibt/gab es die Kombination 4-B-E gar nicht.
Zweites Verständnisproblem: du musst zur Erreichung deines Ergebnisses noch ein DISTINCT über die Ergebnismenge machen.
Das ist nun auch nix anderes als ein GROUP BY über alle Felder und entsprechend teuer.
Wäre da nicht insgesamt ein einfaches GROUP BY in dieser Form
... günstiger?
Ergebnis in meiner Theorie wäre doch
2----------A--------------------C----------1.2.2017 -> hier ist richtigerweise der Satz 1/Artikel 1ausgefiltert
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------E----------1.1.2017
6----------A--------------------F----------1.1.2017
Wenn du dann zu einem dieser Ergebnissätze noch weitere Infos brauchst (Menge, Dauer, Stück, whatever), dann kannst du doch diesen Satz eindeutig über "Artikel, Maschine, Material, max(Datum)" identifizieren.
Grüße
Biber
danke für deine Lösung.
Aber auch mit der habe ich ein bzw. zwei Verständnisprobleme.
Erstes Verständnisproblem:
em-pie hat doch in seinem konstruierten Beispiel eine der Sollbruchstellen aufgezeigt.
1----------A--------------------C----------1.1.2017
2----------A--------------------C----------1.2.2017
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------E----------1.1.2017
6----------A--------------------F----------1.1.2017
In diesen Beispiel würde doch das Material "E" auf zwei Maschinen (A und B) verwendet und für zwei unterschiedliche Artikel (4 und 5).
Dein SELECT würde daraus machen
2----------A--------------------C -> hier ist richtigerweise der Satz 1/Artikel 1ausgefiltert
3----------B--------------------D
4----------B--------------------E --> Hier würde als "Artikel" unvorhersagbar 4 oder 5 herauskommen als FIRST_VALUE()
4----------A--------------------E --> Hier würde als "Artikel" unvorhersagbar 4 oder 5 herauskommen als FIRST_VALUE()
6----------A--------------------F
Es ist somit mindestens eine ausgegebene Zuordnung Material-Maschine-Artikel falsch - im der Realität gibt/gab es die Kombination 4-B-E gar nicht.
Zweites Verständnisproblem: du musst zur Erreichung deines Ergebnisses noch ein DISTINCT über die Ergebnismenge machen.
Das ist nun auch nix anderes als ein GROUP BY über alle Felder und entsprechend teuer.
Wäre da nicht insgesamt ein einfaches GROUP BY in dieser Form
SELECT Artikel, Maschine, Material, max(Datum) as Datum
From t
GROUP BY Artikel, Maschine, Material
Ergebnis in meiner Theorie wäre doch
2----------A--------------------C----------1.2.2017 -> hier ist richtigerweise der Satz 1/Artikel 1ausgefiltert
3----------B--------------------D----------1.1.2017
4----------B--------------------E----------1.1.2017
5----------A--------------------E----------1.1.2017
6----------A--------------------F----------1.1.2017
Wenn du dann zu einem dieser Ergebnissätze noch weitere Infos brauchst (Menge, Dauer, Stück, whatever), dann kannst du doch diesen Satz eindeutig über "Artikel, Maschine, Material, max(Datum)" identifizieren.
Grüße
Biber