一个电商,这个mysql语句该怎么写呢?有经验的同学们来看下 5C

假如移动端在选择衣服时分别选择了过滤条件,码数:x码、xL码,腰型:高腰,发货地:大陆、欧洲,
那sql语句该怎么写呢?过滤条件又是动态可多选的,
表结构如下:
产品表(product):
productId,productName 此表为产品表,如
id1 衣服1
id2 衣服2
id3 衣服3
产品参数记录表(productType):
productId,choiceValueId,此表记录着产品都有那些规格参数
id1 choiceValueId1
id1 choiceValueId2
id1 choiceValueId3
id1 choiceValueId6
id1 choiceValueId8
id2 choiceValueId1
id2 choiceValueId2
id2 choiceValueId3
id2 choiceValueId4
id2 choiceValueId5
id2 choiceValueId7
id3 ..
..
..
产品参数类型key表(productTypeKey):
choiceId , name 此表为类型key表,如码数
choiceId1 码数
choiceId2 腰型
choiceId3 发货地
产品参数类型value表(productTypeValue):
choiceId ,choiceValueId, name 此表为物品类型value表,如衣服的s码
choiceId1 choiceValueId1 s码
choiceId1 choiceValueId2 X码
choiceId1 choiceValueId3 XXL码
choiceId2 choiceValueId4 高腰
choiceId2 choiceValueId5 中腰
choiceId2 choiceValueId6 低腰
choiceId3 choiceValueId7 大陆
choiceId3 choiceValueId8 区洲

8个回答

可以直接把几张表全部关联起来,然后按照条件查询。或者拼接动态sql语句

oShiZu
士卒 关键是要怎么写呢?
一年多之前 回复

select * from product as a right join productType as b on a.productId = b.productId left join productTypeValue as c on b.choiceValueId =c.choiceValueId left join productTypeKey as d on c.choiceId = d.choiceId where c.name in ('x','xl') and d.name = '高腰'

oShiZu
士卒 假如码数:x码、xL码,腰型:高腰,发货地:大陆、欧洲这些条件都加上去的话就达不到预期的效果了
一年多之前 回复

select * from product as a left join (select productId,count(choiceValueId) as valueNum from productType as b left join productTypeValue as c on b.choiceValueId =c.choiceValueId left join productTypeKey as d on c.choiceId = d.choiceId where c.name in ('x','xl','高腰','大陆') group by productId)as e on a.productId=e.productId and e.valueNum=4
后面的4是查询条件的数量 ('x','xl','高腰','大陆')

oShiZu
士卒 目前想到一个办法来动态拼接sql语句,
一年多之前 回复
oShiZu
士卒 不过还是要真心感谢您的回答,用心了,谢谢!
一年多之前 回复
oShiZu
士卒 最终确认通过数字来判断的这个方法不可行,举个例子,一件衣服假如有's','x'、'xl'、'xxl'属性,用户选择了's','x'、'xl'、'xxl'和'高腰',那么按照这个数字的判断就不正确了,valueNum为4,最终会把这件衣服返回,但实际上这件衣服并没有‘高腰’属性,所以这个还是行不通
一年多之前 回复
joywen520
文子 回复oShiZu: select * from product as a left join (select b.productId,sum(d.choiceValueId) as valueNum from productType as b left join productTypeValue as c on b.choiceValueId =c.choiceValueId left join (select choiceId,choiceValueId,case when count(name)>1 then 1 else 0 end as valueNum from productTypeKey where c.name in ('x','xl','高腰','大陆') group by choiceId,choiceValueId) as d on c.choiceId = d.choiceId group by productId)as e on a.productId=e.productId where e.valueNum=3
一年多之前 回复
oShiZu
士卒 我们现在也是这样写的,通过gropu by来判断数值,但发现有问题的,例如,我一件衣服有码数:'x'属性,有'高腰'属性,有'大陆属性',但按用户选择了'x','xl','高腰','大陆'来过滤的话这件衣服就不显示出来了,实际上是要显示出来才是正确的
一年多之前 回复

应该写在移动端里面吧 连接到MySQL 然后查询修改数据

sdwujk160507140150
爱学习的李冬虎 回复qq_42062561: 恩恩
一年多之前 回复
qq_42062561
qq_42062561 你好在吗
一年多之前 回复
oShiZu
士卒 。。。
一年多之前 回复

目前想到一个办法,把答案贴出来,方便有需要的人,
explain
select *
from
(
select
spu.pId,spu.name as spuName,GROUP_CONCAT(choiceV.choiceValueId SEPARATOR ',') as mChoiceValueId, group_concat(choiceV.name SEPARATOR ',') as mChoiceName
from productTypeValue as choiceV
left join productTypeKey as choiceK on choiceV.choiceId = choiceK.choiceId
left join productType as choiceSpu on choiceV.choiceValueId = choiceSpu.choiceValueId
left join product as spu on choiceSpu.pId = spu.pId
where
choiceV.statu = 1
and choiceK.isSearchCondition = 1
group by spu.pId
) as nt where

(
FIND_IN_SET('2258ba1736f711e8976f02004c4f4f50', nt.mChoiceValueId)
or FIND_IN_SET('24490b7636f711e8976f02004c4f4f50', nt.mChoiceValueId)
) #android / ios
and
(
FIND_IN_SET('6b6244ad36f711e8976f02004c4f4f50', nt.mChoiceValueId)
or FIND_IN_SET('5fb49bd9370d11e8976f02004c4f4f50', nt.mChoiceValueId)
);

SELECT
P.productId,
p.productName ,
COUNT(DISTINCT tv.choiceId) AS ct,

GROUP_CONCAT(DISTINCT IF(tk.name = '码数',tv.name,NULL)) AS type1,
GROUP_CONCAT(DISTINCT IF(tk.name = '腰型',tv.name,NULL)) AS type2,
GROUP_CONCAT(DISTINCT IF(tk.name = '发货地',tv.name,NULL)) AS type3,
FROM product p , productType t, productTypeValue tv , productTypeKey tk
WHERE p.productId = t.productId AND t.choiceValueId = tv.choiceValueId AND tv.choiceId = tk.choiceId

AND ((tk.name = '码数' AND tv.name IN('x码','xL码')) OR (tk.name = '腰型' AND tv.name = '高腰') OR (tk.name = '发货地' AND tv.name IN ('大陆','欧洲')))
GROUP BY P.productId
HAVING ct = 3

以上是MySQL的语句。思路 尺码,腰型,发货地 这几个不同维度的条件时and关系。
有两个思路 1.使用exists 检查3个都满足的商品,缺点不能显示商品关联的尺码,腰型等,如果必须显示需要再次关联才能。 2.全联分组,SQL如上,没有明分别检测3个条件是否满足,通过分组后检查满足条件的类类别量 ct=3,来限制3个条件都满足

表结构如下:
产品表(product):productId,productName 此表为产品表,如
id1 衣服1
id2 衣服2
id3 衣服3
产品参数记录表(productType):productId,choiceValueId,此表记录着产品都有那些规格参数
id1 choiceValueId1
id1 choiceValueId2
id1 choiceValueId3
id1 choiceValueId6
id1 choiceValueId8
id2 choiceValueId1
id2 choiceValueId2
id2 choiceValueId3
id2 choiceValueId4
id2 choiceValueId5
id2 choiceValueId7
id3 ..
..
..
产品参数类型key表(productTypeKey):choiceId , name 此表为类型key表,如码数
choiceId1 码数
choiceId2 腰型
choiceId3 发货地
产品参数类型value表(productTypeValue):choiceId ,choiceValueId, name 此表为物品类型value表,如衣服的s码
choiceId1 choiceValueId1 s码
choiceId1 choiceValueId2 X码
choiceId1 choiceValueId3 XXL码
choiceId2 choiceValueId4 高腰
choiceId2 choiceValueId5 中腰
choiceId2 choiceValueId6 低腰
choiceId3 choiceValueId7 大陆
choiceId3 choiceValueId8 区洲

oShiZu
士卒 回复qq_37244548: 这个关联怎么写呢?
一年多之前 回复
qq_37244548
qq_37244548 进行表之间的关联
一年多之前 回复
oShiZu
士卒 。。。。。。。。。。。
一年多之前 回复

像这种几乎不怎么变化得数据,而且后期维护得时候,不会涉及道修改得时候,简单得说,就是类型,码什么得,几乎都是固定,再一个表里加一个字段,用int或者是String都可以区分得,如果需要效率更好,可以分别些sql语句,不是难度,不一定要多表关联,而且这个一个衣服得数据,几乎都是必选项,直接以张表搞定,优化得话,可以写什么函数实现等等

oShiZu
士卒 感谢回答,不过不考虑你这种办法,太勉强,维护工作量太大,我已把答案贴出来,可以参考下
一年多之前 回复
lixiaozhen007
lixiaozhen007 我说了,衣服和裤子啥得可以做分类,也可以做类型区分得一个字段可以代表很多东西得,不是说就1,就2,就3,那么简单得说,再说,首先是实现,所有得类型包含,其次是优化
一年多之前 回复
lixiaozhen007
lixiaozhen007 我百度过这个单表数据不能超过4G得,你想想4G,是什么概念,你懂得,放心得说,
一年多之前 回复
lixiaozhen007
lixiaozhen007 字段多没事,就1,2,3,,4,5之类得多嘛,10个字段到15个字段都不多得,主要是数据得内容多不
一年多之前 回复
oShiZu
士卒 回复lixiaozhen007: 那你一张表得有多大?得有多少个字段???
一年多之前 回复
oShiZu
士卒 回复lixiaozhen007: 一张表实现??电商生活中无数种商品,规格参数也无数种,像杯子、电脑、手机、鞋子等等,每一种商品都有多种规格参数,你一张表实现???
一年多之前 回复
qq_42062561
qq_42062561 你好能帮我下载个文件吗我微信转给你,不想冲会员太浪费了, stm32+pca9685控制舵机机械臂 ,18855995054我的微信号
一年多之前 回复
lixiaozhen007
lixiaozhen007 而且,数据多了,可以分类型啥得,简单得说,就是衣服,裤子,内衣啥得分类,也可以放一起
一年多之前 回复
lixiaozhen007
lixiaozhen007 一张表,一个衣服得数据都是必填项,不存在交叉,一张表足够,也没那么多字段,
一年多之前 回复
Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!