Kom ihåg mig?
Home Menu

Menu


MySQL - välja rader som uppfyller flera villkor

 
Ämnesverktyg Visningsalternativ
Oläst 2013-08-14, 01:20 #1
mephisto73s avatar
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Jan 2008
Inlägg: 730
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
mephisto73s avatar
 
Reg.datum: Jan 2008
Inlägg: 730
Standard 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?
mephisto73 är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-14, 07:56 #2
Johnny Viking Johnny Viking är inte uppkopplad
Medlem
 
Reg.datum: Aug 2011
Inlägg: 273
Johnny Viking Johnny Viking är inte uppkopplad
Medlem
 
Reg.datum: Aug 2011
Inlägg: 273
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.
Johnny Viking är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-14, 12:28 #3
mephisto73s avatar
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Jan 2008
Inlägg: 730
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
mephisto73s avatar
 
Reg.datum: Jan 2008
Inlägg: 730
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!
mephisto73 är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-14, 14:14 #4
Johnny Viking Johnny Viking är inte uppkopplad
Medlem
 
Reg.datum: Aug 2011
Inlägg: 273
Johnny Viking Johnny Viking är inte uppkopplad
Medlem
 
Reg.datum: Aug 2011
Inlägg: 273
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).
Johnny Viking är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-15, 11:58 #5
mephisto73s avatar
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Jan 2008
Inlägg: 730
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
mephisto73s avatar
 
Reg.datum: Jan 2008
Inlägg: 730
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...
mephisto73 är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-15, 12:11 #6
linusoleander linusoleander är inte uppkopplad
Medlem
 
Reg.datum: Feb 2010
Inlägg: 234
linusoleander linusoleander är inte uppkopplad
Medlem
 
Reg.datum: Feb 2010
Inlägg: 234
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';
linusoleander är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-15, 14:02 #7
mephisto73s avatar
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Jan 2008
Inlägg: 730
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
mephisto73s avatar
 
Reg.datum: Jan 2008
Inlägg: 730
Citat:
Ursprungligen postat av linusoleander Visa inlägg
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.
mephisto73 är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-15, 14:55 #8
danjel danjel är inte uppkopplad
Medlem
 
Reg.datum: Nov 2003
Inlägg: 214
danjel danjel är inte uppkopplad
Medlem
 
Reg.datum: Nov 2003
Inlägg: 214
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
danjel är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-15, 15:43 #9
mephisto73s avatar
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
 
Reg.datum: Jan 2008
Inlägg: 730
mephisto73 mephisto73 är inte uppkopplad
Mycket flitig postare
mephisto73s avatar
 
Reg.datum: Jan 2008
Inlägg: 730
Citat:
Ursprungligen postat av danjel Visa inlägg
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.
mephisto73 är inte uppkopplad   Svara med citatSvara med citat
Oläst 2013-08-15, 19:32 #10
Johnny Viking Johnny Viking är inte uppkopplad
Medlem
 
Reg.datum: Aug 2011
Inlägg: 273
Johnny Viking Johnny Viking är inte uppkopplad
Medlem
 
Reg.datum: Aug 2011
Inlägg: 273
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
Johnny Viking är inte uppkopplad   Svara med citatSvara med citat
Svara


Aktiva användare som för närvarande tittar på det här ämnet: 1 (0 medlemmar och 1 gäster)
 

Regler för att posta
Du får inte posta nya ämnen
Du får inte posta svar
Du får inte posta bifogade filer
Du får inte redigera dina inlägg

BB-kod är
Smilies är
[IMG]-kod är
HTML-kod är av

Forumhopp


Alla tider är GMT +2. Klockan är nu 00:18.

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