多对多的属性对应表如何做按照类别的多属性匹配搜索
電商設(shè)計(jì)中常用到的屬性對(duì)應(yīng)表需要做按照類(lèi)別的多屬性匹配功能,舉例建表如下
CREATE TABLE goods_attr (`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id',`goods_id` int(11) DEFAULT '0' COMMENT '商品id',`type` int(11) DEFAULT '0' COMMENT '屬性類(lèi)型:1:商品類(lèi)型 2:支持語(yǔ)言 3:支持平臺(tái)',`value` varchar(50) DEFAULT '' COMMENT '屬性值',PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='商品屬性信息表'; INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('1', '118', '1', '1'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('2', '118', '1', '5'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('3', '118', '1', '8'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('4', '118', '2', '1'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('5', '146', '3', '1'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('6', '146', '1', '1'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('7', '157', '1', '8'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('8', '157', '1', '5'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('9', '157', '2', '1'); INSERT INTO goods_attr (`id`, `goods_id`, `type`, `value`) VALUES ('10', '157', '1', '1');如上所述,goods_id type value組成唯一的一條記錄
比如
首先,118商品擁有三個(gè)類(lèi)型,是一個(gè)復(fù)合類(lèi)型商品 有 1 5 8 三種類(lèi)型
同時(shí),118商品有一個(gè)語(yǔ)言 是1類(lèi)型的語(yǔ)言
同時(shí),118商品有1個(gè)平臺(tái) 是1類(lèi)型平臺(tái)
146商品就只有一個(gè)類(lèi)型是1,一種平臺(tái)是1,而且沒(méi)有語(yǔ)言
然后現(xiàn)在前臺(tái)或者接口調(diào)用處要根據(jù)某個(gè)屬性進(jìn)行反查詢(xún)得到商品id,最常見(jiàn)的地方是商品的屬性搜索,參考
https://s.taobao.com/list?spm=a217l.8087239.620327.1.729cb1d2ofc3E9&q=%E7%94%B5%E9%A5%AD%E7%85%B2&style=grid&seller_type=taobao
可以看到能夠根據(jù)該類(lèi)別商品的屬性進(jìn)行搜索
比如容量 控制方式 等進(jìn)行多屬性匹配搜索。
那么,就需要一個(gè)很復(fù)雜的復(fù)合查詢(xún)才行,采用inner join多次連表也是能做到的,不過(guò)書(shū)寫(xiě)的SQL就比較復(fù)雜,而且很難保證效率。
針對(duì)我們的表 假如要查詢(xún) ?商品類(lèi)型為5和8的復(fù)合類(lèi)型,而且支持語(yǔ)言為1的商品,該如何查詢(xún)呢?
最容易想到的是?
select * from goods_attr where ( type=1 and value in ('5','8') ) or ( type=2 and value in ('1') )但是這樣的查詢(xún)條件必然是不正確的,因?yàn)?只要符合其中一個(gè)條件,那些不相干的記錄也被查出來(lái)了,稍稍改進(jìn)進(jìn)行自鏈接
select * from goods_attr as a left join goods_attr as b on a.goods_id=b.goods_id and (( a.type=1 and a.value in ('5','8') ) and ( b.type=2 and b.value in ('1') ))?
這樣的自鏈接看似是正確的,實(shí)際上偏離了我們要求的同時(shí)滿(mǎn)足復(fù)合屬性的記錄存在,value必須有5 而且又有8 而不是in ('5','8') 所以也是不正確的。
如何得到同時(shí)有5又有8呢?只能這樣寫(xiě)
select a.* from goods_attr as a inner join goods_attr as b on a.goods_id=b.goods_id and a.type=1 and a.value=5 and b.value=8這種情況下能查詢(xún)出 type=1的情況下既有5 又有8 的屬性。那如何加上查詢(xún)type=2的情況下 value=1的屬性條件呢?當(dāng)然是再連接一次!
select c.goods_id from (select a.* from goods_attr as a inner join goods_attr as b on a.goods_id=b.goods_id and a.type=1 and a.value=5 and b.value=8 ) as tmp inner join goods_attr as c on c.goods_id=tmp.goods_id where c.type=2 and c.value=1至此,自鏈接方法講述完畢,如果不想用大量的自鏈接,又該如何做呢?
我想到,可以使用行轉(zhuǎn)列的方式進(jìn)行操作,行轉(zhuǎn)列,借助 group_concat實(shí)現(xiàn)
select goods_id,type, group_concat(value) as v from (select * from goods_attr order by goods_id asc,type asc,value asc ) as u where (type=1 and value in ('5','8')) or (type=2 and value in ('1')) group by goods_id,type然而這樣查詢(xún)出來(lái)的結(jié)果并沒(méi)有自然的排序放入 group_concat中 所以需要強(qiáng)制性指明排序
select goods_id,type, group_concat(value order by goods_id asc,type asc,value asc) as v from goods_attr where (type=1 and value in ('5','8')) or (type=2 and value in ('1')) group by goods_id,type這樣就能強(qiáng)制性拿到排序
?現(xiàn)在得到了屬性的分組,然后我們還要把屬性分類(lèi)和分組的值再次合并形成一列,和剛剛一樣 再次使用group_concat
select group_concat(type,"-",v) as final,goods_id from (select goods_id,type,v from (select goods_id,type, group_concat(value order by goods_id asc,type asc,value asc) as v from goods_attr as u where (type=1 and value in ('5','8')) or (type=2 and value in ('1')) group by goods_id,type) as tmp ) as t group by goods_id很顯然,我們拿到了所有符合的商品屬性的列和商品id,那么再加一條查詢(xún)條件即可或得到我們需要的屬性列表
select goods_id from (select group_concat(type,"-",v) as final,goods_id from (select goods_id,type,v from (select goods_id,type, group_concat(value order by goods_id asc,type asc,value asc) as v from goods_attr as u where (type=1 and value in ('5','8')) or (type=2 and value in ('1')) group by goods_id,type) as tmp) as t group by goods_id ) as f where final='1-5,8,2-1'這樣我們就得到了需要的商品id!!!
因這篇文章探討SQL比較深入,所以這里加一下版權(quán)。
版權(quán)所有,轉(zhuǎn)載需要聲明原文地址?http://www.cnblogs.com/lizhaoyao/p/7199611.html
轉(zhuǎn)載于:https://www.cnblogs.com/lizhaoyao/p/7199611.html
總結(jié)
以上是生活随笔為你收集整理的多对多的属性对应表如何做按照类别的多属性匹配搜索的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: COGS 2274. [HEOI 201
- 下一篇: echarts用法配置