• Hallo liebe Userinnen und User,

    nach bereits längeren Planungen und Vorbereitungen sind wir nun von vBulletin auf Xenforo umgestiegen. Die Umstellung musste leider aufgrund der Serverprobleme der letzten Tage notgedrungen vorverlegt werden. Das neue Forum ist soweit voll funktionsfähig, allerdings sind noch nicht alle der gewohnten Funktionen vorhanden. Nach Möglichkeit werden wir sie in den nächsten Wochen nachrüsten. Dafür sollte es nun einige der Probleme lösen, die wir in den letzten Tagen, Wochen und Monaten hatten. Auch der Server ist nun potenter als bei unserem alten Hoster, wodurch wir nun langfristig den Tank mit Bytes vollgetankt haben.

    Anfangs mag die neue Boardsoftware etwas ungewohnt sein, aber man findet sich recht schnell ein. Wir wissen, dass ihr alle Gewohnheitstiere seid, aber gebt dem neuen Board eine Chance.
    Sollte etwas der neuen oder auch gewohnten Funktionen unklar sein, könnt ihr den "Wo issn da der Button zu"-Thread im Feedback nutzen. Bugs meldet ihr bitte im Bugtracker, es wird sicher welche geben die uns noch nicht aufgefallen sind. Ich werde das dann versuchen, halbwegs im Startbeitrag übersichtlich zu halten, was an Arbeit noch aussteht.

    Neu ist, dass die Boardsoftware deutlich besser für Mobiltelefone und diverse Endgeräte geeignet ist und nun auch im mobilen Style alle Funktionen verfügbar sind. Am Desktop findet ihr oben rechts sowohl den Umschalter zwischen hellem und dunklem Style. Am Handy ist der Hell-/Dunkelschalter am Ende der Seite. Damit sollte zukünftig jeder sein Board so konfigurieren können, wie es ihm am liebsten ist.


    Die restlichen Funktionen sollten eigentlich soweit wie gewohnt funktionieren. Einfach mal ein wenig damit spielen oder bei Unklarheiten im Thread nachfragen. Viel Spaß im ngb 2.0.

MySql - Daten mit mehreren Bedingungen holen

KingJamez

Aktiver NGBler

Registriert
18 Juli 2013
Beiträge
504
Ich möchte eine kleine Produkt Sortierung schreiben, die auf mehrere Werte reagieren soll,
am ende sollen nur Produkte ausgespuckt werden auf die auch alle Filter zutreffen.

Meine Datenbank Tabellen sehen so aus:

[src=text]# products

id | name | etc....
1 | pro1 | ..
2 | pro2 | ..
3 | pro3 | ..



# product_attributes (attribut gruppen)

id | name
1 | Farbe
2 | Hersteller
3 | Breite
4 | Tiefe

# product_attributes_options (attribut optionen)

id | name | attribute_id
1 | blau | 1
2 | grün | 1
3 | 5cm | 3
4 | 7cm | 3
5 | Nokia | 2

# poducts_2_options

product_id | option_id
1 | 1
1 | 3
1 | 5
1 | 2
2 | 1
2 | 3
2 | 5
2 | 2[/src]


Ich übergebe mit get- parametern die attribute und dazu passenden optionen
bsp.:
[src=text]?Hersteller=Nokia&Farbe=blau&Tiefe=5cm[/src]
und möchte am ende nur Produkt 1 zurück bekommen, das enthält zwar zusätzlich auch noch die Farbe grün, spielt ja aber in dem Moment keine große rolle.

Die Tabelle "products" enthält meine eigentlichen Produkte,
Die Tabelle "product_2_options" enthält den bezug zwischen Option und Produkt
Die Tabelle "product_attributes_options" enthält nur die Optionen und die bezüge auf deren eltern attribute
Die Tabelle "product_attributes" enthält nur die Gruppen namen.

Mit einzelnen parametern kann ich relativ leicht mit WHERE filtern. Meine ersten versuche waren dann mit "WHERE in (...)" zu filtern, dann bekomme ich aber zu viele werte zurück, alle wo einer von beiden vorkommt.
Gibt es eine andere Lösung? Ist es überhaupt in einem Query möglich?

Ich habe schon einige Versuche, komme aber leider nicht zum ziel, unten ein paar meiner versuche
[src=text]
// geht nur mit einem match
SELECT
p2o.product_id,
p2o.id,
p2o.option_id,
opt.id AS opt_id,
opt.name AS opt_name,
opt.attribute_id,
attr.id AS attribute_id,
attr.name AS attribute_name

FROM
gc_products_2_attributes_options p2o

JOIN
gc_products_attributes_options opt
ON
opt.id = p2o.option_id

JOIN
gc_products_attributes attr
ON
attr.id = opt.attribute_id

WHERE
attr.name = 'Hersteller'
AND
opt.name = 'Nokia'



SELECT
opt.name,
opt.id,
opt.attribute_id,
prod2opt.id AS prod_opt_id,
prod2opt.product_id AS prod_opt_prod_id,
prod2opt.option_id AS prod_opt_opt_id,
attr.id,
attr.name

FROM
gc_products_attributes_options opt

LEFT JOIN
gc_products_2_attributes_options prod2opt
ON
prod2opt.option_id = opt.id
AND
opt.name = 'Nokia'

LEFT JOIN
gc_products_attributes attr
ON
attr.id = opt.attribute_id
AND
attr.name = 'Hersteller'

// kein ergebnis :(
SELECT
opt.name,
opt.id,
opt.attribute_id,
prod2opt.id AS prod_opt_id,
prod2opt.product_id AS prod_opt_prod_id,
prod2opt.option_id AS prod_opt_opt_id,
attr.id,
attr.name

FROM
gc_products_attributes_options opt

INNER JOIN
gc_products_2_attributes_options prod2opt
ON
prod2opt.option_id = opt.id
AND
opt.name = 'Nokia'
AND
opt.name = '5cm'


INNER JOIN
gc_products_attributes attr
ON
attr.id = opt.attribute_id
AND
attr.name = 'Hersteller'
AND
attr.name = 'Breite'


[/src]

Perspektivisch habe ich überlegt nur die Produkt id´s zu holen und die Produkt- Daten dann mit einer Schleife aus meinem Produkt-Model zu holen.
 

epiphora

aus Plastik
Veteran

Registriert
14 Juli 2013
Beiträge
3.894
Ort
DE-CIX
Eine Sache: In Deinen Testdaten ist das Attribut Tiefe doch für gar kein Produkt vergeben, oder sehe ich das falsch?

Du musst doch nur noch mit den Produkten joinen und dann nach [kw]products.id[/kw] gruppieren und dann überprüfen, ob noch immer alle angeforderten Attribute vorhanden sind. Oder übersehe ich etwas? Ich hab das mal realisiert, indem ich einfach überprüfe, ob die gefilterten Elemente noch die zusammen gruppierten Attributsnamen enthalten:

[src=mysql]SELECT products.id

FROM `products`

JOIN `gc_products_2_attributes_options`
ON gc_products_2_attributes_options.product_id = products.id

JOIN `gc_products_attributes_options`
ON gc_products_attributes_options.id = gc_products_2_attributes_options.option_id

JOIN `gc_products_attributes`
ON gc_products_attributes.id = gc_products_attributes_options.attribute_id

WHERE (gc_products_attributes.name = 'Hersteller' AND gc_products_attributes_options.name = 'Nokia')
OR (gc_products_attributes.name = 'Farbe' AND gc_products_attributes_options.name = 'grün')
OR (gc_products_attributes.name = 'Breite' AND gc_products_attributes_options.name = '5cm')

GROUP BY products.id

HAVING GROUP_CONCAT(gc_products_attributes.name ORDER BY gc_products_attributes.name) = 'Breite,Farbe,Hersteller'[/src]

Aber mal ein ganz anderer Ansatz: Verwendest Du ein Framework? Kann es nicht sein, dass das vielleicht schon eine fertige Filter-Option für solche Zwecke bereitstellt?
 

KingJamez

Aktiver NGBler

Registriert
18 Juli 2013
Beiträge
504
  • Thread Starter Thread Starter
  • #3
Vielen dank für die Hilfe, so hat´s geklappt. Nein ich verwende kein Framework was mir diese Funktion bietet.
Nein du siehst es richtig, in meinen Testdaten ist das Attribut "tiefe" nicht vergeben, nicht jedes Produkt enthält auch immer alle Attribute- Gruppen.
 
Oben