拆分关联区域数据
需求:通過對運輸表拆分出對應的城市再關聯商品生成所有的記錄.
解決方法:通過split_string結合存儲過程的for循環解決該問題.
Mysql:
DROP PROCEDURE IF EXISTS pro_gen_area; CREATE PROCEDURE `pro_gen_area`() begindeclare i int;declare j int;declare k int;declare areastr varchar(200);DECLARE rownumber int;DECLARE len int;DECLARE setcnt int;/***1 作用:生成所有的可配送的區域數據2 描述: 這里只是清洗了shenl_carrycity力的c_showarea2的"["和"]"3 通過for循環加載c_showarea2到表shenl_bi_tmp_ETL_area內**/DROP TABLE IF EXISTS shenl_bi_tmparea;CREATE TEMPORARY TABLE shenl_bi_tmparea ASSELECT A.* FROM(SELECT @row_number:=@row_number+1 AS rank,REPLACE(REPLACE(REPLACE(c_showarea2,'][',','),'[',''),']','') as area FROM (SELECT fareid,c_showarea2 FROM shenl_carrycity)area, /* (SELECT fareid,c_showarea2 FROM shenl_carrycity WHERE c_showarea2 <> '[0]')area,*/(SELECT @row_number:=0) AS tORDER BY fareid DESC) A;DROP TABLE IF EXISTS shenl_bi_tmp_ETL_area;create TEMPORARY table shenl_bi_tmp_ETL_area(rank int,area int,str VARCHAR(200),inserttime TIMESTAMP);SELECT MAX(rank) INTO rownumber FROM shenl_bi_tmparea;set i=1;set j=1;while i<=rownumber doSELECT LENGTH(area)-LENGTH(REPLACE(area,',',''))+1 into len FROM shenl_bi_tmparea WHERE rank = i;while j <= len doinsert into shenl_bi_tmp_ETL_area(rank,str,inserttime) SELECT i,split_string(area, ',',j),now() FROM shenl_bi_tmparea WHERE rank = i; set j = j+1;end while;set j = 1;set len=0;set i=i+1;end while;/***1 作用:生成所有的可配送明細數據(粒度到每個城市和商品)2 描述: 這里只是清洗了shenl_carrycity力的c_showarea2的"["和"]"3 通過for循環加載str(即城市id)入參(判斷shenl_carrycity、shenl_goods關聯)與到表shenl_bi_temp_carryable**/DROP TABLE IF EXISTS shenl_bi_temp_carryable;CREATE TABLE `shenl_bi_temp_carryable` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增標識',`sellnum` int(4) DEFAULT '0',`gid` bigint(8) NOT NULL DEFAULT '0',`g_title` varchar(250) DEFAULT NULL,`g_price` decimal(10,2) DEFAULT NULL,`bargain` tinyint(1) DEFAULT '0',`rate_good` int(4) DEFAULT '0',`rate_num` int(4) DEFAULT '0',`rate` decimal(14,4) DEFAULT NULL,`g_status` tinyint(1) DEFAULT '1',`pushed` tinyint(1) DEFAULT '0',`c_showarea2` varchar(200),`area` varchar(200),`inserttime` timestamp DEFAULT now(),g_addtime datetime DEFAULT NULL,g_lasttime datetime DEFAULT NULL,PRIMARY KEY (`id`));set k=1;SELECT MAX(rank) INTO setcnt FROM(SELECT @row_number:=@row_number+1 AS rank,str FROM (SELECT DISTINCT str AS str FROM shenl_bi_tmp_ETL_area)A,(SELECT @row_number:=0) AS t)A;while k <= setcnt DOSELECT str INTO areastr FROM (SELECT @row_number:=@row_number+1 AS rank,str FROM (SELECT DISTINCT str AS str FROM shenl_bi_tmp_ETL_area)A,(SELECT @row_number:=0) AS t)A WHERE rank = k;INSERT INTO shenl_bi_temp_carryable(sellnum, gid, g_title, g_price, bargain, rate_good, rate_num, rate, g_status, pushed, c_showarea2, area, inserttime,g_addtime,g_lasttime)SELECT sellnum,B.gid,B.g_title,B.g_price,B.bargain,B.rate_good,B.rate_num,B.rate_good/CASE B.rate_num WHEN 0 THEN 1 END AS rate,B.g_status,B.pushed,A.c_showarea2,areastr,now(),g_addtime,g_lasttimeFROM shenl_carrycity AJOIN shenl_goods BON A.fareid = B.logistools AND B.g_num >0WHERE INSTR(A.c_showarea2,CONCAT(CONCAT('[',areastr),']')) >0 AND B.g_status = 1 AND B.g_num >0 AND g_vscreen=1 AND g_index = 1;/*此處限制是為了精準匹配到area,通過不加CONCAT 則會匹配錯誤。如匹配 24,c_showarea2的樣例數據如:224,24 不加CONCAT會匹配成224*/SET k = k +1;END WHILE;END;部分代碼解讀:
1 split_string是一個字符串拆分函數,傳入參數有:要拆分的字符串、分隔符、對應位置
DROP FUNCTION IF EXISTS split_string; CREATE FUNCTION `split_string`( stringToSplit VARCHAR(256), sign VARCHAR(12), position INT) RETURNS varchar(256) CHARSET utf8 BEGINRETURN REPLACE(SUBSTRING(SUBSTRING_INDEX(stringToSplit, sign, position),LENGTH(SUBSTRING_INDEX(stringToSplit, sign, position -1)) + 1), sign, ''); END; -- 執行示例: SELECT split_string('a|b|c','|',3) AS split UNION SELECT split_string('a|b|c','|',2) AS split執行結果:
split |
c |
b |
2 split_string是一個字符串拆分函數,傳入參數有:要拆分的字符串、分隔符、對應位置
CREATE TEMPORARY TABLE shenl_bi_tmparea AS SELECT A.*FROM (SELECT @row_number:=@row_number+1 AS rank,REPLACE(REPLACE(REPLACE(c_showarea2,'][',','),'[',''),']','') as areaFROM(SELECT fareid,c_showarea2 FROM shenl_carrycity) area,(SELECT @row_number:=0) AS tORDER BY fareid DESC ) A;1) 這里@row_number類似于記數變量,隨著記錄集的遍歷自動加1.
2) CREATE TEMPORARY TABLE shenl_bi_tmparea AS SELECT 是以SELECT的結果集創建一個臨時表.
3)注意這里將c_showarea2字段里的’][‘替換為了’,’
3 逐行拆分出每行的area值
SELECT MAX(rank) INTO rownumber FROM shenl_bi_tmparea;SET i=1;SET j=1;WHILE i<=rownumber doSELECT LENGTH(area)-LENGTH(REPLACE(area,',',''))+1 into len FROM shenl_bi_tmparea WHERE rank = i;WHILE j <= len doINSERT INTO shenl_bi_tmp_ETL_area(rank,str,inserttime) SELECT i,split_string(area, ',',j),now() FROM shenl_bi_tmparea WHERE rank = i; SET j = j+1;END WHILE;SET j =1;SET len=0;SET i=i+1; END WHILE; ???????????1) 借助于WHILE循環,按照序號1到MAX(rank)對外層就行循環控制
????2) 借助于WHILE循環,按照序號1到area字段里的逗號數+1對內層就行循環控制.
????3) 將最終結果插入到shenl_bi_tmp_ETL_area表中
4 ?通過商品里的c_showarea2再匹配shenl_bi_tmp_ETL_area表里的地區,最終得到每個商品應該配送的區域
SET k=1;SELECT MAX(rank) INTO setcnt FROM(SELECT @row_number:=@row_number+1 AS rank,str FROM(SELECT DISTINCT str AS str FROM shenl_bi_tmp_ETL_area)A,(SELECT@row_number:=0) AS t)A;WHILE k <= setcnt DOSELECT str INTO areastr FROM (SELECT @row_number:=@row_number+1 AS rank,str FROM(SELECT DISTINCT str AS str FROM shenl_bi_tmp_ETL_area)A,(SELECT@row_number:=0) AS t)A WHERE rank = k;INSERT INTO shenl_bi_temp_carryable(sellnum,gid, g_title, g_price, bargain, rate_good, rate_num, rate, g_status, pushed,c_showarea2, area, inserttime,g_addtime,g_lasttime)SELECT sellnum,B.gid,B.g_title,B.g_price,B.bargain,B.rate_good,B.rate_num,B.rate_good/CASE B.rate_num WHEN 0 THEN 1 END AS rate,B.g_status,B.pushed,A.c_showarea2,areastr,now(),g_addtime,g_lasttimeFROM shenl_carrycity AJOIN shenl_goods BON A.fareid = B.logistools AND B.g_num >0WHERE INSTR(A.c_showarea2,CONCAT(CONCAT('[',areastr),']')) >0 AND B.g_status =1 AND B.g_num >0 AND g_vscreen=1 AND g_index =1;/*此處限制是為了精準匹配到area,通過不加CONCAT 則會匹配錯誤。如匹配 24,c_showarea2的樣例數據如:224,24 不加CONCAT會匹配成224*/SET k = k +1;END WHILE;1)? 通過SELECT DISTINCT str AS str FROM shenl_bi_tmp_ETL_area獲取所有的區域信息
2)? 通過表關聯,借助WHILE循環將結果插入到shenl_bi_temp_carryable中
補注:
1) c_showarea2數據示例見下:
2) shenl_bi_temp_carryable里的數據示例:
總結
- 上一篇: 怎么从u盘上拷贝文件 如何复制U盘中的文
- 下一篇: 随机推送数据