maik87
Goto Top

Filtern- Wenn vorhanden dann den, sonst einen anderen Datensatz

Hallo,

sorry für die blöde Überschrift, mir fiel jedoch nichts besseres ein ;)

Nehmen wir mal an, ich habe eine einfache Tabelle:

Artikelnummer - Lagerort
1 - 1
2 - 1
3 - 1
3 - 2
4 - 2

Ich benötige nun eine Abfrage, die jede Artikelnummer nur einmal ausgibt und in den zweiten Spalte den Lagerort. Ist der Artikel an Lagerort 1 verfügbar, dann möchte ich, dass dieser Datensatz ausgegeben wird, sonst der des anderen Lagerortes.

Also so:
1 - 1
2 - 1
3 - 1
4 - 2

Geht das in einer gemeinsamen Abfrage oder muss ich zwei mit UNION zusammenführen?

SELECT Artikelnummer, Lagerort FROM ArtLager WHERE Lagerort = 1
UNION
SELECT Artikelnummer, Lagerort FROM ArtLager WHERE Artikelnummer NOT IN (SELECT Artikelnummer, Lagerort FROM ArtLager WHERE Lagerort = 1);

Content-ID: 197919

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

Ausgedruckt am: 21.11.2024 um 17:11 Uhr

nxclass
nxclass 30.01.2013 um 12:44:57 Uhr
Goto Top
Hi, man könnte ja einfach nach Artikelnummer Gruppieren.
Maik87
Maik87 30.01.2013 um 12:46:35 Uhr
Goto Top
Woher ist dann sichergestellt, dass bevorzugt Lagerort 1 kommt?
nxclass
nxclass 30.01.2013 aktualisiert um 12:51:49 Uhr
Goto Top
Woher ist dann sichergestellt, dass bevorzugt Lagerort 1 kommt?
eigentlich gar nicht - die meisten DB Systeme nutzen dann den "ersten" gefundenen Wert.
ABER: es gibt natürlich die Möglichkeiten wie zB die Aggregat Funktionen, welche das regeln können - das kommt dann aber auf dein DB System an.
Das einfachste wäre natürlich ein MIN() zu nutzen.

SELECT Artikelnummer, MIN(Lagerplatz)
...
GROUP BY Artikelnummer
Maik87
Maik87 30.01.2013 aktualisiert um 13:04:21 Uhr
Goto Top
> Woher ist dann sichergestellt, dass bevorzugt Lagerort 1 kommt?
eigentlich gar nicht - die meisten DB Systeme nutzen dann den "ersten" gefundenen Wert.

Da ist das Problem face-smile

ABER: es gibt natürlich die Möglichkeiten wie zB die Aggregat Funktionen, welche das regeln können - das kommt dann
aber auf dein DB System an.
Das einfachste wäre natürlich ein MIN() zu nutzen.

Leider in dem Fall nicht. Es ist ein vereinfachtes Beispiel. Produktiv muss ich es umsetzen können auf Strings, leere Felder etc. Aggregat Funktionen scheiden daher leider aus.
LianenSchwinger
LianenSchwinger 30.01.2013 um 13:14:07 Uhr
Goto Top
... dann gib doch mal ein paar mehr Angaben. Wir sind ja Willens zu helfen. face-smile

- Datenbanksystem
- konkrete Lagerortbezeichnungen
- Rangfolge der Lagerorte

Gruß Jörg
Maik87
Maik87 30.01.2013 um 13:40:19 Uhr
Goto Top
Es läuft eine MySQL-Datenbank Version 5.5.29

Die Lagerorte waren nur ein Beispiel.

Die Tabelle kann auch so aussehen:

Artikelnummer - Lagerort
1 - Berlin
2 - Berlin
3 - Berlin
3 - Hamburg
4 - Hamburg

Nun gibt es auch Tabellen

Abteilung - Name - Vertreter - Frei
EDV - Meyer - - X
EDV - Schulz - X - X
Einkauf - Müller - -
Einkauf - Henrichs - X - X

Hier möchte ich von jeder Abteilung eine Person haben, die frei ist. Zunächst der "nicht-Vertreter". Hat dieser keine Zeit, dann der Vertreter.

Ich könnte noch eine Menge Beispiele kreieren.

Kann ich mit MIN und MAX auch auf alphabetische Reihenfolgen zugreifen?
LianenSchwinger
LianenSchwinger 30.01.2013 aktualisiert um 15:07:29 Uhr
Goto Top
Gibt es in Beispiel 1 nur Berlin und Hamburg? Dann geht MIN(), da Berlin < Hamburg ist.

Beispiel 2 könnte z.B. so klappen.

SELECT a.abteilung AS Abteilung,
       IFNULL(SUBSTRING_INDEX(GROUP_CONCAT(a.name ORDER BY a.vertreter SEPARATOR '*'),'*', 1),  
              'keiner frei') AS Name  
FROM (SELECT DISTINCT b.abteilung FROM xy_tabelle b) AS c
LEFT JOIN xy_tabelle AS a USING(abteilung)
WHERE a.frei IS NOT NULL
GROUP BY a.abteilung

Gruß Jörg
LianenSchwinger
LianenSchwinger 30.01.2013 aktualisiert um 14:58:34 Uhr
Goto Top
Beispiel 2 müsste auch so gehen

SELECT x.abteilung,
       IFNULL(IFNULL(y.name,z.name),'keiner frei') Name  
FROM (SELECT DISTINCT a.abteilung 
      FROM xy_tabelle a) AS x
LEFT JOIN (SELECT b.abteilung, b.name 
           FROM xy_tabelle AS b 
           WHERE b.vertreter IS NULL AND b.frei IS NOT NULL) AS y USING(abteilung)
LEFT JOIN (SELECT c.abteilung, c.name 
           FROM xy_tabelle AS c 
           WHERE b.vertreter IS NOT NULL AND b.frei IS NOT NULL) AS z USING(abteilung)

Halt ohne Aggregat-Funktion.

Gruß Jörg
nxclass
nxclass 31.01.2013 um 13:01:13 Uhr
Goto Top
Kann ich mit MIN und MAX auch auf alphabetische Reihenfolgen zugreifen?
nicht sinnvoll

Dann lege dir doch eine Tabelle an mit Lagerort und Entfernung bzw Priorität. Nun kannst du mit GROUP und MAX(priorität) arbeiten.