WN

WN (https://www.wn.se/forum/index.php)
-   Serversidans teknologier (https://www.wn.se/forum/forumdisplay.php?f=4)
-   -   MySQL - välja rader som uppfyller flera villkor (https://www.wn.se/forum/showthread.php?t=1058798)

mephisto73 2013-08-14 01:20

MySQL - välja rader som uppfyller flera villkor
 
I brist på terminologi så vill jag välja de rader i t1 som har associerade rader i t3 som uppfyller godtyckligt antal villkor.

Kod:

SELECT t1.* FROM `t1`
LEFT JOIN t2 ON t1.a=t2.b
LEFT JOIN t3 ON t2.a=t3.b
WHERE t3.c IN ('this','also')
AND t3.c IN ('that','too')
AND ...
GROUP BY t1.a ORDER BY t1.d ASC

Jag vill alltså få ut de rader i t1 som uppfyller samtliga villkor, men som det ser ut nu så returneras inga rader om jag har mer än ett villkor (
Kod:

WHERE t3.c IN ('this','also')
).

Några tips?

Johnny Viking 2013-08-14 07:56

Normalt sett tillåter ju en left join att ta med t1 i ditt fall även om inget i t3 matchar.

Men i med att du lägger ett villkor under den normala WHERE satsen som gäller för t3, så får du inga resultat från t1 heller.

Du kan i LEFT join ON köra ON t3.rel_id = t1.id AND t3.c IN ('that', 'too')

På så sätt får du bara t3-resultat som matchar villkoren du satt för t3-joinen.

mephisto73 2013-08-14 12:28

Jag var nog inte tydlig i min fråga. Låt mig visa ett exempel. Anta att jag har tre tabeller:

products
Kod:

ID | name | price
1  Fiat Panda  2500
2  VW Golf  3500
3  Peugot 2008 4200
4  Peugot 2008 4800

product_properties
Kod:

ID | product_id | property_id
1  1  1
2  1  4
3  2  3
4  2  4
5  3  2
6  3  6
6  4  1
6  4  6

property_values
Kod:

ID | property_group |value
1  color  red
2  color  green
3  color  blue
4  type  compact
5  type  SUV
6  type  crossover

Jag vill kunna filtrera på t.ex. röda bilar och få följande:

Kod:

1  Fiat Panda  2500
4  Peugot 2008 4800

eller t.ex. gröna bilar av typen crossover och få:

Kod:

3  Peugot 2008 4200
Om någon kan hjälpa mig i rätt riktning med hur queryn kan se ut så blir jag väldigt tacksam! :)

Johnny Viking 2013-08-14 14:14

Jag missförstod dig lite. Men tror följande blir rätt.

Kod:

SELECT * FROM products P
LEFT JOIN product_properties PP ON PP.product_id = P.ID
LEFT JOIN property_values PV ON PV.ID = PP.property_ID
WHERE PV.ID IN(1,6)

Detta hämtar endast matchande röd (1) och crossover (6).

mephisto73 2013-08-15 11:58

Problemet är att den lösningen har en OR-logik. Den listar de produkter som är röda ELLER är crossover. Jag behöver de produkter som har egenskap 1 OCH egenskap 2 OCH egenskap 3..., eller snarare de produkter som har egenskap_array_1 OCH egenskap_array_2 o.s.v.

T.ex. vill jag i mitt filter vill se alla bilar som är blå ELLER röda OCH som är av typen crossover ELLER SUV...

linusoleander 2013-08-15 12:11

Kod:

SELECT * FROM products P
LEFT JOIN product_properties PP ON PP.product_id = P.ID
LEFT JOIN property_values PV ON PV.ID = PP.property_ID
WHERE property_values.value = 'crossover' AND property_values.value = 'red';


mephisto73 2013-08-15 14:02

Citat:

Ursprungligen postat av linusoleander (Inlägg 20475574)
Kod:

SELECT * FROM products P
LEFT JOIN product_properties PP ON PP.product_id = P.ID
LEFT JOIN property_values PV ON PV.ID = PP.property_ID
WHERE property_values.value = 'crossover' AND property_values.value = 'red';


Returnerar noll rader!?

Jag tror dock att jag är en lösning på spåren:

Kod:

SELECT bp.ID FROM `base_products` bp
JOIN product_properties pp ON pp.product_id=bp.ID
JOIN product_properties_values ppv ON pp.property_value_id = ppv.ID
WHERE ppv.value IN ('16','21') OR ppv.value IN ('blå')
GROUP BY ID HAVING COUNT(*) = 2

Där jag skippar "AND" mellan villkorsgrupperna och istället använder "OR", samtidigt som jag villkorar gruppningen av de returnerade raderna:

Kod:

GROUP BY ID HAVING COUNT(*) = 2
Där 2 motsvarar antalet egenskapsgrupper eller villkorsgrupper jag vill att de returnerade produkterna skall uppfylla.

danjel 2013-08-15 14:55

Du kan inte dela upp det i fler queries..?
alltså typ
1. select from product_properties where..
2. ta bort duplicerade product id
3. select from products where id IN(...)

Personligen tycker jag joins blir så komplext

mephisto73 2013-08-15 15:43

Citat:

Ursprungligen postat av danjel (Inlägg 20475587)
Du kan inte dela upp det i fler queries..?
alltså typ
1. select from product_properties where..
2. ta bort duplicerade product id
3. select from products where id IN(...)

Personligen tycker jag joins blir så komplext

Jag vill egentligen inte det då det känns som att man väljer den "enkla vägen ut". ;)

Dock funkar lösningen enligt ovan, den gör precis det jag ville att den ska göra.

Johnny Viking 2013-08-15 19:32

Om du kör PV.ID IN (1,2,3,4,5,6) så får du ju alla resultat möjliga.

Mellan varje siffra är ju ett OR, så du ska därmed få varje matchande.

Blir det inte så, så är det ju konstigt :)


Alla tider är GMT +2. Klockan är nu 14:22.

Programvara från: vBulletin® Version 3.8.2
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Svensk översättning av: Anders Pettersson