shaendle
Goto Top

SQL-Abfrage für Artikel mit mehrern Varianten

Hallo,

ich stehe vor dem Problem, eine Abfrage über eine Aritkeldatenbank zu machen, welche Artikel herausfiltert, die mehrere Varianten haben. Also z.B. Hose mit Farbe blau und Größe 58.

Artikel ist eine Tabelle und die verwendeten Varianten sind in einer extra Tabelle gespeichert.

Beispiel

tabelle_artikel
tabelle_artikel_varianten
tabelle_varianten_values

Mit einem INNER JOIN und einer UNION-Abfrage bekomme ich das nicht geregelt, da ich im Prinzip zwei Bedingungen habe. Zum einen muss die ID der Variante übereinstimmen und zum anderen die ID des Values (zb. blau oder 58). Für den Artikel stehen aber in der Tabelle tabelle_artikel_varianten zwei Einträge drin. Für jede Variante einen Zeile mit der ID der Variante und der ID des Values

Ich hoffe ich habe mich einigermaßen klar ausgedrückt.

Hat jemand einen Tipp wie ich sowas ohne mehrere Abfragen geregelt bekomme?

Viele Grüße
Sascha

Content-Key: 94350

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

Printed on: April 26, 2024 at 22:04 o'clock

Member: AndreasHoster
AndreasHoster Aug 13, 2008 at 14:09:49 (UTC)
Goto Top
Na ja, ganz ohne Unterabfrage geht sowas nicht.
Aber im Prinzip:
select .... (Deine Select Abfrage samt Inner Join etc.)
WHERE (((tabelle_artikel.ID) In (SELECT ID FROM tabelle_artikel_varianten GROUP BY ID HAVING Count(*)>1 )))

Die SELECT ID FROM tabelle_artikel_varianten GROUP BY ID HAVING Count(*)>1 filtert alle IDs aus den Varianten raus, die mehr als einmal vorkommen und mit < where ID in (Select ... > nehmen wir dann nur die IDs, die in der Unterabfrage auch rausgesucht wurden. Das müsste ja das sein, was Du willst.

Ansonsten wäre noch interessant welches DBMS, weil verschiedene DBMS nicht immer alle SQL Möglichkeiten unterstützen und manchmal andere Syntax haben können.
Member: Biber
Biber Aug 13, 2008 at 16:33:30 (UTC)
Goto Top
Moin shaendle,

willkommen im Forum.
</OT>
Im Bereich "Datenbanken" findest Du folgenden Hinweis:
Bitte bei Fragen im Bereich Datenbanken auch immer das verwendete Datenbanksystem angeben!

Beispiele: mySQL 4.0 oder Oracle 9i oder Microsoft SQLServer Express etc.
Insbesondere SQL-bezogene Fragen können ohne diese Informationen nicht sinnvoll beantwortet werden.


Ich weiss, es ist so langweilig und hölzern formuliert, dass es kein normaler Mensch zu Ende liest. Ich suche auch immer noch eine schöne peppige, verständliche Formulierung, die nicht oberlehrerhaft klingt.
Bitte: Tipps dazu Tag und Nacht gern an mich per PN.
</OT>

Die Struktur ist mir in höchstem Grade unklar.
Poste doch bitte mal eine Skizze davon (also relevante Attribute je Tabelle).
Was ist denn mit Artikeln ohne Varianten? Fallen die untern Tisch?
Oder meinst Du eigentlich mit der heutigen Artikel-Tabelle "Artikelgruppen" oder Kategorien wie Hemden, Blusen, Hosen oder Krawatten, die dann jeweils spezifische Attribute haben?

"DB"-System ist vermutlich M$-Access, alle anderen Tools hätten sich vermutlich automatisch beendet...

Grüße
Biber
Member: shaendle
shaendle Aug 13, 2008 at 18:49:34 (UTC)
Goto Top
Danke für die schnelle Antwort. Okay, da hab ich wohl ein paar Infos vergessen.

Das Ganze läuft auf MySQL 5.x

Hier nochmal der Versuch die Struktur zu erläutern. Im Wesentlichen soll der Kunde in einem Onlineshop einen Filter auf Artikelvarianten setzen können. Wenn jemand nach blauen Klamotten in Größe 58 sucht, sollen ihm diesen angezeigt werden. Egal ob Hose, Rock, T-Shirt. Hauptsache blau und Größe 58.

Um das Ganze zu verkomplizieren kann aber auch noch Hersteller und Artikelgruppe gewählt werden. Dann also alle blauen Jeanshosen von Levis in Größe 48.

Die Tabellen:

Artikel:

Artikel_ID
Artikel_HERSTELLER (nur eine ID)
Artikel_GROUP (nur eine ID)


Artikelvarianten:

Varianten_ID
Artikel_ID
Variante_PREIS


Variantenarten_der_Artikelvariante:

Varianten_ID
Variantenart_ID
Variantenartvalue_ID


Variantenart (Farbe, Größe):

Variantenart_ID
Variantenart_NAME (z.B. Farbe)


Variantenartvalue (Blau, Rot, 58, 45):

Variantenartvalue_ID
Variantenartvalue_NAME (z.B. Blau)


Das Problem ist nun, dass in der Tabelle Variantenarten_der_Artikelvariante mehrere Datensätze pro Artikelvariante stehen. Die Hose ist ja blau und soll die Größe 58 haben. Der Verweis auf den Hersteller und die Aritkelgruppe steht in der Tabelle Artikel. Hersteller und Aritkelgruppe ist ebenfalls eine extra Tabelle.

So, ich hoffe jetzt ist die Problemstellung etwas klarer geworden.

Wäre super wenn ich einen Denkanstoß bekäme. Bin mittlerweile "betriebsblind"...

Viele Grüße
Sascha
Member: shaendle
shaendle Aug 13, 2008 at 18:50:24 (UTC)
Goto Top
Hallo Andreas,

Danke für die schnelle Antwort. Okay, da hab ich wohl ein paar Infos vergessen.

Das Ganze läuft auf MySQL 5.x

Hier nochmal der Versuch die Struktur zu erläutern. Im Wesentlichen soll der Kunde in einem Onlineshop einen Filter auf Artikelvarianten setzen können. Wenn jemand nach blauen Klamotten in Größe 58 sucht, sollen ihm diesen angezeigt werden. Egal ob Hose, Rock, T-Shirt. Hauptsache blau und Größe 58.

Um das Ganze zu verkomplizieren kann aber auch noch Hersteller und Artikelgruppe gewählt werden. Dann also alle blauen Jeanshosen von Levis in Größe 48.

Die Tabellen:

Artikel:

Artikel_ID
Artikel_HERSTELLER (nur eine ID)
Artikel_GROUP (nur eine ID)


Artikelvarianten:

Varianten_ID
Artikel_ID
Variante_PREIS


Variantenarten_der_Artikelvariante:

Varianten_ID
Variantenart_ID
Variantenartvalue_ID


Variantenart (Farbe, Größe):

Variantenart_ID
Variantenart_NAME (z.B. Farbe)


Variantenartvalue (Blau, Rot, 58, 45):

Variantenartvalue_ID
Variantenartvalue_NAME (z.B. Blau)


Das Problem ist nun, dass in der Tabelle Variantenarten_der_Artikelvariante mehrere Datensätze pro Artikelvariante stehen. Die Hose ist ja blau und soll die Größe 58 haben. Der Verweis auf den Hersteller und die Aritkelgruppe steht in der Tabelle Artikel. Hersteller und Aritkelgruppe ist ebenfalls eine extra Tabelle.

So, ich hoffe jetzt ist die Problemstellung etwas klarer geworden.

Wäre super wenn ich einen Denkanstoß bekäme. Bin mittlerweile "betriebsblind"...

Viele Grüße
Sascha
Member: AndreasHoster
AndreasHoster Aug 15, 2008 at 14:31:43 (UTC)
Goto Top
Ich glaube, ich sehe jetzt das Problem.

Du willst nach Farbe und Größe filtern können, aber die stehen nicht in verschiedenen Feldern der Tabellen, sondern sowohl Größe als auch Farbe stehen in Variantenarten_der_Artikelvariante.Variantenartvalue_ID und der Feldinhalt von Variantenarten_der_Artikelvariante.Variantenart_ID legt fest ob es Farbe, Größe oder sonstwas ist.
D.h. ich habe nicht einen Datensatz in dem Größe und Farbe steht, sondern 2 Datensätze und in einem steht die Größe und in einem anderen die Farbe.
Richtig?

Da müsste man dann mit 2 Unterabfragen arbeiten und dann die Ergebnisse nehmen, die in beiden drin sind.
Die gesamten Joins sind mir jetzt zu aufwendig. Gehen wir davon aus, daß Du es so gejoint hast, daß das Ergebnis so aussieht (im folgenden JOIN genannt):
Artikel_ID, Variantenart_Name, Variantenartvalue_Name (die Felder brauchen wir auf alle Fälle)
Select * from JOIN where Artikel_ID in (Select Artikel_ID from JOIN where Variantenart_Name='Farbe' and Variantenartvalue_Name='Blau') and Artikel_ID in (Select Artikel_ID from JOIN where Variantenart_Name='Größe' and Variantenartvalue_Name='58')

Ich hoffe, das reicht als Anstoß, es syntaktisch korrekt zu machen ist mir gerade zu aufwendig.
Member: Biber
Biber Aug 15, 2008 at 17:50:04 (UTC)
Goto Top
Na ja,
so richtig die sprechenden Infos bekommen wir ja ohnehin nicht raus.
Die einzigen "lesbaren" Werte, nämlich
Variantenart.Variantenart_NAME ("FARBE") und
Variantenart_Value.VariantenartValue_NAME ("blau")
..stehen ja in der der WHERE-Klausel.
Und die Informationen über Artikel_HERSTELLER und Artikel_GROUP hängen noch in der Luft (da kennen wir die Refernenztabellen nicht.

Also bekommen wir eigentlich nur zwei interessante Infos zurück
- kein Satz gefunden, falls kein Satz gefunden wird oder
- den ArtikelPreis und die Artikel_ID

SELECT Art.ARTIKEL_ID AV.Variante_preis From 
Variantenart VA,
Variantenarten_der_Artikelvariante AVA,
Variantenartvalue VAV,
Artikel Art
Where 
VA.Variantenart_ID = AVA.Variantenart_ID and
VAV.Variantenartvalue_Id = AVA.Variantenartvalue_ID and
VA.Varianten_ID =  AV.Varianten_ID AND
Art.ARTIKEL_ID = AV.ARTIKEL_ID AND
VAV.Variantenart_NAME = 'FARBE' AND  
VAV.Variantenartvalue_Name = 'Blau'   

Aber so kann man/frau keine Abfragen formulieren bzw wartbar gestalten.

@shaendle
Brich die Versuche hier ab.
Es ist vollkommen in Ordnung, wenn irgendein Theoretiker/Fanatiker die Datenbank-Persistierung bis zur 12ten Normalform getrieben hat. Jedenfalls wenn ihr 800 TeraByte an Daten verwalten wollt.

Aber der Zugriff speziell für Abfragen muss nicht über 1:1-Zugriffe auf die physische Struktur erfolgen.
Sondern darf auf eine logische Struktur erfolgen. Dafür sind Datenbanken da.
Bau Dir da ein, zwei Views drüber,
die den Artikel (Id, Bezeichnung, HerstellerNAME, GruppenNAME) und die Varianten-Seite (Artikel,
VariantenName, VariantenPreis, VariantenValueNameA ... VariantenvalueNameX) als 2 Tabellen anzeigen.
In views brauchst Du dann auch keinen Unfug mehr wie "Variantenartvalue_Name" als Feldnamen.
Und feuer dann die Ad-hoc-Queries auf Views ab.

Grüße
Biber
Member: shaendle
shaendle Aug 16, 2008 at 21:56:02 (UTC)
Goto Top
Also ich hab jetzt Deinen Ansatz mal versucht. Die einzige Abfrage die zunächst keinen MySQL-Fehler ergibt ist folgende:

SELECT a.*, ah.*, sg.group_parent, sg.group_code, av.* FROM shop_article a INNER JOIN shop_article_html ah ON a.article_id = ah.article_id INNER JOIN shop_article_group sg ON a.article_group = sg.group_id INNER JOIN shop_article_var av ON a.article_id = av.article_id INNER JOIN shop_article_var_value avv ON av.variante_id = avv.variante_id WHERE ah.article_lang = 'ger' AND av.article_language = 'ger' AND a.article_active = '1' AND a.article_code <> '' AND av.article_price > '0' IN (SELECT a.article_id FROM shop_article a INNER JOIN shop_article_html ah ON a.article_id = ah.article_id INNER JOIN shop_article_group sg ON a.article_group = sg.group_id INNER JOIN shop_article_var av ON a.article_id = av.article_id INNER JOIN shop_article_var_value avv ON av.variante_id = avv.variante_id WHERE ah.article_lang = 'ger' AND av.article_language = 'ger' AND a.article_active = '1' AND a.article_code <> '' AND av.article_price > '0' AND avv.variante_var = '1' AND avv.variante_var_value='108') GROUP BY av.article_id ORDER BY av.article_special_price ASC, av.article_price ASC LIMIT 0,9  

ok. Es sind halt noch ein paar WHERE-Klauseln versteckt und es werden ein paar Tabellen mehr gejoint. Allerdings bekomme ich so alle Einträge angzeigt.

Das mit den Subselects hab ich mir auch schon halb gedacht. Aber es will einfach nicht klappen face-sad

Vielleicht hast Du ja noch eine Idee??...