日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

多对多的属性对应表如何做按照类别的多属性匹配搜索

發布時間:2025/3/21 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 多对多的属性对应表如何做按照类别的多属性匹配搜索 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

電商設計中常用到的屬性對應表需要做按照類別的多屬性匹配功能,舉例建表如下

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 '屬性類型:1:商品類型 2:支持語言 3:支持平臺',`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商品擁有三個類型,是一個復合類型商品 有 1 5 8 三種類型

同時,118商品有一個語言 是1類型的語言

同時,118商品有1個平臺 是1類型平臺

146商品就只有一個類型是1,一種平臺是1,而且沒有語言

然后現在前臺或者接口調用處要根據某個屬性進行反查詢得到商品id,最常見的地方是商品的屬性搜索,參考

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

可以看到能夠根據該類別商品的屬性進行搜索

比如容量 控制方式 等進行多屬性匹配搜索。

那么,就需要一個很復雜的復合查詢才行,采用inner join多次連表也是能做到的,不過書寫的SQL就比較復雜,而且很難保證效率。

針對我們的表 假如要查詢 ?商品類型為5和8的復合類型,而且支持語言為1的商品,該如何查詢呢?

最容易想到的是?

select * from goods_attr where ( type=1 and value in ('5','8') ) or ( type=2 and value in ('1') )

但是這樣的查詢條件必然是不正確的,因為 只要符合其中一個條件,那些不相干的記錄也被查出來了,稍稍改進進行自鏈接

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

?

這樣的自鏈接看似是正確的,實際上偏離了我們要求的同時滿足復合屬性的記錄存在,value必須有5 而且又有8 而不是in ('5','8') 所以也是不正確的。

如何得到同時有5又有8呢?只能這樣寫

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

這種情況下能查詢出 type=1的情況下既有5 又有8 的屬性。那如何加上查詢type=2的情況下 value=1的屬性條件呢?當然是再連接一次!

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

至此,自鏈接方法講述完畢,如果不想用大量的自鏈接,又該如何做呢?

我想到,可以使用行轉列的方式進行操作,行轉列,借助 group_concat實現

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

然而這樣查詢出來的結果并沒有自然的排序放入 group_concat中 所以需要強制性指明排序

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

這樣就能強制性拿到排序

?現在得到了屬性的分組,然后我們還要把屬性分類和分組的值再次合并形成一列,和剛剛一樣 再次使用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,那么再加一條查詢條件即可或得到我們需要的屬性列表

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比較深入,所以這里加一下版權。

版權所有,轉載需要聲明原文地址?http://www.cnblogs.com/lizhaoyao/p/7199611.html

轉載于:https://www.cnblogs.com/lizhaoyao/p/7199611.html

總結

以上是生活随笔為你收集整理的多对多的属性对应表如何做按照类别的多属性匹配搜索的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。