2016-06-12 4 views
1

Ich habe 3 Tabellen in meiner DatenbankMysql Abfrage von 3 Tabellen und wo Klausel

# Items 
id - name 
---------- 
1 - Item A 
2 - Item B 
3 - Item C 

.

# Traits 
id - name 
---------- 
1 - Color 
2 - Grade 
3 - Size 

.

# Values 
id - item_id - trait_id - value 
---------- 
1 - 1 - 1 - red 
1 - 2 - 1 - green 
1 - 3 - 1 - red 
1 - 1 - 2 - 90% 
1 - 2 - 2 - 45% 
1 - 3 - 2 - 80% 
1 - 1 - 3 - 4 inches 
1 - 2 - 3 - 5 inches 
1 - 3 - 3 - 9 inches 

In Laravel, konnte ich alle Einzelteile mit ihren Eigenschaften und Werte erhalten mit "belongsTo" [$ this-> belongsTo ('App \ Traits', 'trait_id');] in Value-Modell die Ergebnisse zu erhalten so wie:

--- Item A 
Color: red 
Grade: 90% 
Size: 4 inches 

--- Item B 
Color: green 
Grade: 45% 
Size: 5 inches 

.. etc 

von Code wie folgt:

$items = Items::get(); 
foreach ($items as $item) { 
    echo '<h2>'.$item->name.'</h2>'; 
    foreach ($item->values as $value) { 
     echo '<b>'.$value->trait->name . '</b>: '; 
     echo $value->value . '<br>'; 
    } 
} 

Doch was konnte ich nicht tun, ist, dass ich diese Ergebnisse zu filtern, für Beispiele, ich nur Artikel benötigen, das seine Farbe ist "rot" und seine Note größer als 70%?

Wenn Sie nicht Larave verwenden, können Sie es in reinen mysql-Abfragen zu schreiben, kann ich einen Weg finden, es in Laravel zu tun, wenn ich auf die Idee kommen .. Danke

+2

'id' keinen Zweck in der Wertetabelle dient (das ist, btw, eine schlechte Wahl des Namens). Ein guter Tipp, wenn Sie ein EAV-Modell verwenden, besteht darin, für jeden Datentyp separate Tabellen zu erstellen. – Strawberry

+0

@Strawberry Eigentlich ist es das erste Mal, dass ich über EAV-Modell weiß, alle obigen Strukturen kamen von meinem Kopf, ohne etwas über EAV zu wissen, ich lese mehr darüber und sehe, was für eine solche Vorgehensweise am besten ist, danke für den Tipp – Ahmad

Antwort

1

Filtering Artikel/Entitäten durch (mehrere) Attribut-Wert-Paare ist einer der Nachteile der EAV model. Es gibt einige Möglichkeiten, das zu erreichen. Eine davon ist die Items Tisch mit Traits und Values einmal pro Bedingung beizutreten:

select i.* 
from Items i 
join `Values` v1 on v1.item_id = i.id 
join `Values` v2 on v2.item_id = i.id 
join Traits t1 on t1.id = v1.trait_id 
join Traits t2 on t2.id = v2.trait_id 
where t1.name = 'Color' and v1.value = 'red' 
    and t2.name = 'Grade' and v2.value > 70 

sqlfiddle

Sie können auch ein Ergebnis bekommen mit den Säulen verwenden Schwenken (item_id, Farbe, Grad):

select v.item_id 
    , max(case when t.name = 'Color' then v.value end) as Color 
    , max(case when t.name = 'Grade' then v.value end) as Grade 
from `Values` v 
join Traits t on t.id = v.trait_id 
group by v.item_id 
having Color = 'red' and Grade > 70 

Dieses Ergebnis kann mit der Tabelle Items verknüpft werden, um die gefilterten Elemente zu erhalten. Eine Änderung kann auch in einer WHERE-IN Zustand verwendet werden:

select * from Items 
where id in (
    select v.item_id 
    from `Values` v 
    join Traits t on t.id = v.trait_id 
    group by v.item_id 
    having max(case when t.name = 'Color' then v.value end) = 'red' 
    and max(case when t.name = 'Grade' then v.value end) > 70 
); 

sqlfiddle

Ein anderer Ansatz:

select * from Items 
where id in (
    select v.item_id 
    from `Values` v 
    join Traits t on t.id = v.trait_id 
    where t.name = 'Color' and v.value = 'red' 
    or t.name = 'Grade' and v.value > 70 
    group by v.item_id 
    having count(v.item_id) = 2 
); 
+0

Danke sehr viel Paul! Das erste Mal, dass ich das EAV-Modell kenne, lese ich mehr darüber. – Ahmad