带join的sql查询

9q78igpj  于 2021-06-20  发布在  Mysql
关注(0)|答案(1)|浏览(319)

我正在为电子商务商店创建产品过滤器。我有一个product表,characteristics表和一个存储product\u id,characteristics\u id和一个筛选器值的表。
商店产品-id,名称
商店特性-id,值(json)
商店价值-产品id、特征id、价值
我可以构建一个查询,通过一个值获取所有产品,如下所示:

SELECT `p`.* FROM `shop_products` `p` 
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id` 
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))

很好用。此外,我可以修改此查询,并通过属于同一特征组(具有相同的特征标识)的多个值获取所有产品,如下所示:

SELECT `p`.* FROM `shop_products` `p` 
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id` 
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
OR ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='indoor'))

但是,当我尝试为具有不同特征id的多个条件创建一个查询时,却一无所获

SELECT `p`.* FROM `shop_products` `p` 
LEFT JOIN `shop_values` `fv` ON `p`.`id` = `fv`.`product_id` 
WHERE ((`fv`.`characteristic_id`=3) AND (`fv`.`value`='outdoor'))
AND ((`fv`.`characteristic_id`=5) AND (`fv`.`value`='white'))

我猜它不起作用,因为在这种情况下我使用了错误的and运算符,因为shop\ U values表中没有同时具有特征\ id 3和5的记录。
所以我的问题是如何组合或修改我的查询以获得所有相关的产品,或者像这样存储数据是一个缺陷,我需要创建一个不同类型的shop\u values表?

rn0zuynd

rn0zuynd1#

使用聚合。还可以将元组与 in 条款。所以:

SELECT p.*
FROM shop_products p JOIN
     shop_values v
     ON p.id = v.product_id
WHERE (v.characteristic_id, v.value) IN ( (3, 'outdoor'), (5, 'white'))
GROUP BY p.id
HAVING COUNT(DISTINCT v.characteristic_id) = 2;

笔记:
不必要地转义列和表别名(带反记号)只会使查询更难写和读。
一般来说,使用 SELECT p.* 以及 GROUP BY p.id 真的,真的很糟糕。一个例外是当您按唯一键或主键分组时。ansi标准实际上支持后一种形式。
LEFT JOIN 不需要。需要在表之间找到匹配项,逻辑才能工作。
使用 AND 以及 OR 对我来说很好 WHERE 条款。mysql恰好支持具有 IN ,这在一定程度上简化了逻辑。

相关问题