受欢迎的博客标签

类似京东的商品筛选功能的实现数据结构

Published

http://m.blog.csdn.net/weizengxun/article/details/7025983

 

数据表结构
1、属性表(attributeid ,....)
2、商品表(productid ,.....)
3、属性值表(attributevalueId,attributeId,......)
4、商品_属性值表(productid attributevalue)(关键表)

先添加商品分类,
添加商品分类后,添加该商品分类的属性。
如添加衣服分类,该分类有颜色、尺码属性。
再如手机分类,该分类有品牌属性,网络制式属性的。
添加分类属性后,还有为该属性添加属性值,如颜色属性的属性值为:蓝色,红色,卡其,迷彩等属性值。
先在开始添加商品,添加商品时选择相应的分类后,若该分类下有属性择显示属性与属性值,用户选择属性值后,提交信息并在商品_属性值表中添加以下数据。
如我选择了颜色属性(假设attributeid =1)下的属性值为蓝色(attributevalueId=1)和红色(假设attributevalueid =2),尺码(假设attributeid =2)为M的属性(假设attributevalueid =3)
那么他存入商品_属性表表的数数据形式为:
productid  attributevalue
1                 1_2_3
2                 1_3
不知大家理清楚了吗?
一个商品分类有多个属性,每个属性下有多个属性值,
一个商品可以选择多个属性值(如,蓝色,红色,M,XXL)等属性

好了表结构就先理到这。下面开始查选了。
这里还有有个难点就是如何拼接属性值。
现在假设我们的筛选条件为颜色为蓝色,尺码的M的衣服
那么我传入的属性为1_3
首先我们先把传入的属性进行拆分并存入临时表 #temp中(当然这之前要先创建好这个临时表)
使用while循环拆分‘1_3’
set @strValue='1_3';
WHILE LEN(@strValue)>0
BEGIN
INSERT #temp SELECT LEFT(@strValue,CHARINDEX('_',@strValue+'_')-1)
INSERT test SELECT LEFT(@strValue,CHARINDEX('_',@strValue+'_')-1)
SET @strValue=LTRIM(STUFF(LTRIM(@strValue),1,CHARINDEX('_',LTRIM(@strValue)+'_'),''))
--INSERT test values( @strValue)

END


----关键字CHARINDEX为返回符合一定条件的字符串所在的位置
CHARINDEX('_',@strValue+'_')此处相当于
CHARINDEX('_','1_3_') 那么返回的应是1,
CHARINDEX('_',@strValue+'_')-1 再减1则为0
然后用Left来窃取,窃取得到1,并插入临时表。
然后把窃取到的部分去掉,让@strValue=‘3_’
SET @strValue=LTRIM(STUFF(LTRIM(@strValue),1,CHARINDEX('_',LTRIM(@strValue)+'_'),''))
以此类推,最后存入临时表的数据为
strValue
1
3
接下来就是查找了

SELECT [ProductId]
      ,[AttributeValue]
  FROM [dbo].[Product_Attribute] where not exists(select * from test
where charindex('_'+cast(strValue as nvarchar(222))+'_' , '_'+[AttributeValue]+'_')=0)

现在来解释这句话,
先来拆分一下吧,首先是这句的意思(strValue 为(临时表中的字段),AttributeValue为产品所选择的属性值
select * from #tempwhere charindex('_'+strValue +'_' , '_'+[AttributeValue]+'_')=0
查找#temp表中值不在AttributeValue中的记录,
假设AttributeValue=‘1_3_4_8’,strValue =0,则有记录,
假设AttributeValue=‘1_3_4_8’,strValue =3,则没有记录,
假设AttributeValue=‘1_3_4_8’,strValue =4,则没有记录,
其实是这样子的
如strValue =1,则charindex('_1_','_1_3_4_8_')
在_1_3_4_8_中能找到与_1_匹配的项吗?找到则返回大于0的值,找不到则返回0
如果传过来的属性值在产品的属性值中有不存在的项则证明该产品的属性不符合传过来的属性
最后用 not exists
如果传过来的属性在产品属性值中都存在,not exists(select * from #tempwhere charindex('_'+strValue +'_' , '_'+[AttributeValue]+'_')=0)是个条件成立的则该商品符合条件

听起来有点复杂呀,还是我表达不清楚。
在表述一遍。
先把传过来的要匹配的属性拆分后存入临时表,
然后在拿临时表中的每一项与商品的属性值匹配,
如果不存在(not exists)这个情况(即临时表中的属性值不在产品的属性值的情况)(临时表中的属性值(即传过来的属性值)),则该商品符合条件。


绕了半天不知大家有没有看明白...........

商品有(1_3_4_8)属性,
假设传过来的属性为1_3,则该产品符合条件,
假设传过来的属性为1_3_4,则该商品也符合条件
假设传过来的商品属性为1_4_9,则该商品不符合条件因为9不在产品的属性中。