本文主要講一下筆者在工作中遇到的一些邏輯比較復雜的sql語句,下面是具體寫法:
SELECT IF ( LOCATE('familyKey', link, 1) = 0, NULL, SUBSTRING( link, LOCATE('familyKey', link, 1) + LENGTH('familyKey') + 1, IF ( LOCATE( '&', link, LOCATE('familyKey', link, 1) ) = 0, LENGTH(link), LOCATE( '&', link, LOCATE('familyKey', link, 1) ) - ( LOCATE('familyKey', link, 1) + LENGTH('familyKey') + 1 ) ) ) ) familyKey FROM illustrations;
這條語句是將illustrations表中的link字段,如:
...&episType=239&familyKey=90897&illustrationId=6837275...
這樣的字條串中familyKey=后面的90897這樣的編號取出來,說白了就是將字符串按關鍵字截取,得到的數據可組成新表進行下一步數據分析工作。
我們也可以將其分拆一下,寫成下面的語句:
SELECT IF(strbegin=0,NULL,SUBSTRING(link,strbegin+strlen+1,IF(strend=0,LENGTH(link),strend-(strbegin+strlen+1)))) familyKey,mainId FROM ( SELECT mainId,link,strbegin,LOCATE('&',link,strbegin) strend, LENGTH('familyKey') strlen FROM ( SELECT mainId,link,LOCATE('familyKey',link,1) strbegin FROM illustrations ) tmp) tmp;
這樣看起來就有條理多了,兩條語句中都涉及了IF條件判斷這些所謂的動態查詢的知識點,寫完還是小有成就感。
下面介紹一下mysql5.7中的一大亮點改進——對Json數據類型的支持
CREATE TABLE maingroup_id_parentId AS SELECT n1.id AS parentId,n2.id AS id FROM nav n1,nav n2 WHERE n1.meta->'$.model' = n2.parent_meta->'$.model' AND n1.meta->'$.spec' = n2.parent_meta->'$.spec' AND n1.meta->'$.lang' = n2.parent_meta->'$.lang' AND n1.meta->'$.startup' = n2.parent_meta->'$.startup' AND n1.meta->'$.localMarketOnly' = n2.parent_meta->'$.localMarketOnly' AND n2.nav_table = 'nav-mainGroup-table' AND n1.nav_table <> 'nav-mainGroup-table';
這條語句是將nav表中建立在以model,spec,lang,startup,localMarketOnly這幾個關鍵字為聯系的基礎上的上下層級關系找出來,建成子表maingroup_id_parentId,然后做進一步數據整理。語句中用到了meta這個Json類型的字段,其使用方式簡便、表義清晰,十分適合對類似帶數據參數的請求地址的存儲。在處理大數據量的表間關系時,上面的用法可能就不實用了,因為效率太差,一條語句可能很久都跑不出來,盲目地等待是沒有任何意義的,我是不會做這種事情,所以我們必須找到更高效的關聯方案。這里可將這些關鍵字對應的信息從Json字段中提出來單獨作為一個字段,並建立索引,然后將它們進行匹配:
-- pnc字段關鍵字提取 ALTER TABLE pnc ADD pnc_number VARCHAR(20) generated always AS (json_extract(meta,'$.pnc')) virtual; ALTER TABLE pnc ADD drawingVar VARCHAR(8) generated always AS (json_extract(meta,'$.drawingVar')) virtual; ALTER TABLE pnc ADD drawing VARCHAR(8) generated always AS (meta->"$.drawing") virtual; ALTER TABLE pnc ADD subGroup VARCHAR(8) generated always AS (json_extract(meta,'$.subGroup')) virtual; ALTER TABLE pnc ADD mainGroup VARCHAR(8) generated always AS (json_extract(meta,'$.mainGroup')) virtual; ALTER TABLE pnc ADD spec VARCHAR(150) generated always AS (json_extract(meta,'$.spec')) virtual; ALTER TABLE pnc ADD model VARCHAR(50) generated always AS (json_extract(meta,'$.model')) virtual; -- pnc建索引 ALTER TABLE pnc ADD INDEX link(pnc_number,drawingVar,drawing,subGroup,mainGroup,spec,model); -- 修改bom表 ALTER TABLE bom ADD pnc_number VARCHAR(20) generated always AS (json_extract(parent_meta,'$.pnc')) virtual; ALTER TABLE bom ADD drawingVar VARCHAR(8) generated always AS (json_extract(parent_meta,'$.drawingVar')) virtual; ALTER TABLE bom ADD drawing VARCHAR(8) generated always AS (parent_meta->"$.drawing") virtual; ALTER TABLE bom ADD subGroup VARCHAR(8) generated always AS (json_extract(parent_meta,'$.subGroup')) virtual; ALTER TABLE bom ADD mainGroup VARCHAR(8) generated always AS (json_extract(parent_meta,'$.mainGroup')) virtual; ALTER TABLE bom ADD spec VARCHAR(150) generated always AS (json_extract(parent_meta,'$.spec')) virtual; ALTER TABLE bom ADD model VARCHAR(50) generated always AS (json_extract(parent_meta,'$.model')) virtual; -- bom建索引 ALTER TABLE bom ADD INDEX link(pnc_number,drawingVar,drawing,subGroup,mainGroup,spec,model); -- 造表間關系 DROP TABLE IF EXISTS pnc_bom_id; CREATE TABLE pnc_bom_id SELECT bom.id AS bomId,pnc.id AS pncId FROM nissan_bom bom,nissan_pnc pnc WHERE bom.pnc_number=pnc.pnc_number AND bom.drawingVar=pnc.drawingVar AND bom.drawing=pnc.drawing AND bom.mainGroup=pnc.mainGroup AND bom.subGroup=pnc.subGroup AND bom.spec=pnc.spec AND bom.model=pnc.model;