I have three tables, for example:
watch table
id(int) name(varchar) ref(int)
1 tissot 1234567
2 addidas 7654321
3 nike 8976543
property table
id(int) name(varchar)
1 water_resistant
2 material_body
3 material_bracelet
4 watch_type
property_material table
watch_id property_id value
1 1 200
1 2 steel
1 3 leather
1 4 quartz
2 1 50
2 2 plastic
2 3 leather
2 4 quartz
3 1 100
3 2 steel
3 3 rubber
3 4 mechanical
I want get all watches which have properties for example:
Help me please create query. Properties can be about 100. In ideal i want get result:
watch_id name ref water_res mat_body mat_bracelet watch_type
1 tissot 1234 200 steel leather quartz
I'm try:
select
w.*, pm.value,pm.property_id
from
watch w
join
property_material pm
on w.id = pm.watch_id
where
pm.pid in (1,2,3)
and
pm.value in ('100','Steel','Leather');
But this query return all records, when value is Steel or Leather, bur I need where material_body is Steel and material_bracelet is Leather, for example.
UPDATE : What you are think about this query?
select
name, ref
from
watch w
join
(SELECT w.id
FROM watch w
JOIN property_material pm on w.id = pm.watch_id
WHERE (pm.property_id = 1 AND pm.value > 100)
OR (pm.property_id = 2 AND pm.value IN ('steel','plastic'))
OR (pm.property_id = 3 AND pm.value IN ('leather','rubber'))
OR (pm.property_id = 4 AND pm.value = 'quartz')
Group by w.id
Having count(*) = 4) as t1
on t1.id = w.id;
LAST UPDATE :
select
w.name,
max(if(pm.property_id='1',pm.value,'')) water_resistant,
max(if(pm.property_id='2',pm.value,'')) material_body,
max(if(pm.property_id='3',pm.value,'')) material_bracelet,
max(if(pm.property_id='4',pm.value,'')) watch_type
from
watch w
join
(
SELECT w.id
FROM watch w
JOIN property_material pm on w.id = pm.watch_id
WHERE (pm.property_id = 1 AND pm.value > 100)
OR (pm.property_id = 2 AND pm.value IN ('steel','plastic'))
OR (pm.property_id = 3 AND pm.value IN ('leather','rubber'))
OR (pm.property_id = 4 AND pm.value = 'quartz')
Group by w.id
Having count(*) = 4
) as t1 on t1.id = w.id
join property_material pm on w.id = pm.watch_id
GROUP BY w.id
Here you have several queries that fill your needs. But as you see, they are all independent. That is why I ask in the comments what exactly you need.
For more tests use this SQL Fiddle sample code using your provided sample data.
EDIT Added new query to have all conditions and all results on one set. Check SQL Fiddle sample code here .
SELECT w.name,ref,property_id,value
FROM watch w
JOIN property p on w.id = p.id
JOIN property_material pm on p.id = pm.property_id
WHERE (p.id = 1 AND pm.value > 100)
OR (p.id = 2 AND pm.value IN ('steel','plastic'))
OR (p.id = 3 AND pm.value IN ('leather','rubber'))
OR (p.id = 4 AND pm.value = 'quartz');
Independent queries:
SELECT w.name Watch_name, p.name Property_name, pm.value Property_value
FROM watch w
JOIN property_material pm ON w.id = pm.watch_id
JOIN property p ON p.id = pm.property_id
WHERE p.id = 1
AND pm.value > 100;
WATCH_NAME PROPERTY_NAME PROPERTY_VALUE
tissot water_resistant 200
Another one:
SELECT w.name Watch_name, p.name Property_name, pm.value Property_value
FROM watch w
JOIN property_material pm ON w.id = pm.watch_id
JOIN property p ON p.id = pm.property_id
WHERE p.id = 2
AND pm.value IN ('steel','plastic');
WATCH_NAME PROPERTY_NAME PROPERTY_VALUE
tissot material_body steel
addidas material_body plastic
nike material_body steel
Another one:
SELECT w.name Watch_name, p.name Property_name, pm.value Property_value
FROM watch w
JOIN property_material pm ON w.id = pm.watch_id
JOIN property p ON p.id = pm.property_id
WHERE p.id = 3
AND pm.value IN ('leather','rubber');
WATCH_NAME PROPERTY_NAME PROPERTY_VALUE
tissot material_bracelet leather
addidas material_bracelet leather
nike material_bracelet rubber
Another one:
SELECT w.name Watch_name, p.name Property_name, pm.value Property_value
FROM watch w
JOIN property_material pm ON w.id = pm.watch_id
JOIN property p ON p.id = pm.property_id
WHERE p.id = 4
AND pm.value = 'quartz';
WATCH_NAME PROPERTY_NAME PROPERTY_VALUE
tissot watch_type quartz
addidas watch_type quartz
The only possibility i know is to make a join to the properties table for each property, like so (i modified your given example):
select w.*, pm1.value,pm1.pid ,pm2.value,pm2.pid
from watch w
join property_material pm1 on w.id = pm1.watch_id AND pm1.pid = 1 and pm1.value = '100'
join property_material pm2 on w.id = pm2.watch_id AND pm2.pid = 2 and pm2.value IN ('Steel','Lather');
select watch_table.id,watch_table.name,ref,property_id,value from watch_table join property_table on watch_table.id=property_table.id
join property_material on property_table.id=property_material.property_id
where WHERE property.id = 3 AND property_material.value IN ('leather','rubber');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.