Mysql多对多关系多条件

标签 mysql sql many-to-many

我有三个表,例如:

看表

id(int)  name(varchar)  ref(int)
1        tissot         1234567
2        addidas        7654321
3        nike           8976543

属性表

id(int)  name(varchar)
1        water_resistant
2        material_body
3        material_bracelet
4        watch_type

属性_ Material 表

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

我想获取所有具有属性的 watch ,例如:

  • 防水 >= 100
  • material_body = 钢或塑料
  • material_bracelet = 皮革或橡胶
  • watch 类型 = quartz 。

请帮我创建查询。属性可以在 100 左右。 在理想情况下,我想要得到结果:

watch_id name    ref   water_res mat_body mat_bracelet watch_type
1        tissot  1234   200       steel    leather      quartz

我正在尝试:

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');

但是这个查询返回所有记录,当值为 Steel 或 Leather 时,但是我需要 material_body 是 Steel 和 material_bracelet 是 Leather,例如。

更新:您对这个查询有什么看法?

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;

最后更新:

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

最佳答案

这里有几个可以满足您需求的查询。但如你所见,它们都是独立的。这就是为什么我在评论中询问您到底需要什么。

要进行更多测试,请使用此 SQL Fiddle sample code使用您提供的示例数据。

编辑 添加了新查询以将所有条件和所有结果都放在一个集合中。检查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');

独立查询:

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

另一个:

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

另一个:

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

另一个:

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

关于Mysql多对多关系多条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13063497/

相关文章:

sql - 删除特定列为空的行

mysql - 在 HAVING 和 WHERE 子句之间使用 OR 运算符的 SQL 查询

mysql - 我需要多对多关系数据库的帮助

mysql 插入错误...不知道出了什么问题

MySQL - 从 INNER JOIN 获取记录而不是在日期之间

sql - SQL Server 中按两列计数?

asp.net-web-api - EF5 代码首先使用 ASP.NET Web API : Update entity with many-to-many relationship

Laravel 4 Eloquent ORM : How to update a pivot table entry that has composite primary keys

php - 如果有值则更新行,如果没有则插入

php - 从 PHP 访问数据库的最佳方式是什么?