Mysql應用總結
1 層次樹型查詢
Mysql需要藉助自定義函數getChildLst 和Mysql自帶的FIND_IN_SET函數實現層次查詢,ABC是數據庫名稱。
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Function structure for getChildLst
-- ----------------------------
DROP FUNCTION IF EXISTS `getChildLst`;
DELIMITER ;;
CREATE DEFINER=`ABC`@`%` FUNCTION`getChildLst`(rootId INT) RETURNS varchar(1000) CHARSET utf8
BEGIN
DECLARE sTemp VARCHAR(1000);
DECLARE sTempChd VARCHAR(1000);
SET sTemp = '$';
SET sTempChd =cast(rootId as CHAR);
WHILE sTempChd is not null DO
SET sTemp = concat(sTemp,',',sTempChd);
SELECT group_concat(RULE_ID) INTO sTempChd FROM TB_RTA_CORE_CHECK_RULEwhere FIND_IN_SET(PARENT_ID ,sTempChd)>0;
END WHILE;
RETURN sTemp;
END
;;
DELIMITER ;
查詢示例語句:
SELECT RULE_ID,PARENT_ID,RULE_NAME,ORDER_CODEFROM TB_RTA_CORE_CHECK_RULE WHERE FIND_IN_SET(RULE_ID, getChildLst(#ruleId#))ORDER BY PARENT_ID,ORDER_CODE
FIND_IN_SET函數語法介紹:
假如字符串str 在由N 子鏈組成的字符串列表strlist 中,則返回值的範圍在 1 到 N 之間。
一個字符串列表就是一個由一些被‘,’符號分開的子鏈組成的字符串。如果第一個參數是一個常數字符串,而第二個是type SET列,則 FIND_IN_SET() 函數被優化,使用比特計算。
如果str不在strlist 或strlist 爲空字符串,則返回值爲 0 。如任意一個參數爲NULL,則返回值爲 NULL。這個函數在第一個參數包含一個逗號(‘,’)時將無法正常運行。
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
返回2因爲b 在strlist集合中放在2的位置從1開始
select FIND_IN_SET('1','1'); 返回 就是1 這時候的strlist集合有點特殊 只有一個字符串 其實就是要求前一個字符串 一定要在後一個字符串集合中 才返回 大於0的數
select FIND_IN_SET('2','1,2');返回2
select FIND_IN_SET('6','1'); 返回0
注意:
select * from treenodes where FIND_IN_SET(id,'1,2,3,4,5');
使用find_in_set函數一次返回多條記錄
id 是一個表的字段 然後每條記錄分別是id等於1,2,3,4,5的時候
有點類似in (集合)
select * from treenodes where id in (1,2,3,4,5);
2.按字段刪除重複記錄
1、查找表中多餘的重複記錄,重複記錄是根據單個字段(peopleId)來判斷
select * from people
where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)
2、刪除表中多餘的重複記錄,重複記錄是根據單個字段(peopleId)來判斷,只留有rowid最小的記錄
delete from people
where peopleId in (select peopleId from people group by peopleId having count(peopleId) > 1)
and rowid not in (select min(rowid) from people group by peopleId having count(peopleId )>1)
3、查找表中多餘的重複記錄(多個字段)
select * from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
4、刪除表中多餘的重複記錄(多個字段),只留有rowid最小的記錄
delete from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)
5、查找表中多餘的重複記錄(多個字段),不包含rowid最小的記錄
select * from vitae a
where (a.peopleId,a.seq) in (select peopleId,seq from vitae group by peopleId,seq having count(*) > 1)
and rowid not in (select min(rowid) from vitae group by peopleId,seq having count(*)>1)
比方說在A表中存在一個字段“name”,而且不同記錄之間的“name”值有可能會相同,
現在就是需要查詢出在該表中的各記錄之間,“name”值存在重複的項;
Select Name,Count(*) From A Group By Name Having Count(*) > 1
如果還查性別也相同大則如下:
Select Name,sex,Count(*) From A Group By Name,sex Having Count(*) > 1
實例1:按照BATCH_ID,FILE_NAME字段去重,保留CRT_DATE較小者
DELETE FROM tb_ctl_collect_log WHERE(BATCH_ID,FILE_NAME) IN (
SELECT a.BATCH_ID,a.FILE_NAME FROM
(
SELECT BATCH_ID,FILE_NAME FROM tb_ctl_collect_log GROUP BYBATCH_ID,FILE_NAME HAVING COUNT(*)>1
AND EXISTS (SELECT MIN(CRT_DATE) AS CRT_DATE FROM tb_ctl_collect_logGROUP BY BATCH_ID,FILE_NAME HAVING
COUNT(*)>1)
)a
);
3. You can't specify target table for update in FROMclause錯誤解決
delete from tbl where id in
(
select max(id) from tbl a where EXISTS
(
select 1 from tbl bwhere a.tac=b.tac group by tac HAVING count(1)>1
)
group by tac
)
改寫成下面就行了:
delete from tbl where id in
(
select a.id from
(
select max(id) id from tbl a where EXISTS
(
select 1 from tbl bwhere a.tac=b.tac group by tac HAVING count(1)>1
)
group by tac
) a
)
4 mysql數據導出命令(mysqldump )和導入命令(source )
導出TB_RTC_DIM_ORG_DEV至文件TB_ RTC _DIM_ORG_DEV中
-h 主機IP –u 數據庫用戶名 –p 數據庫密碼 storm 數據庫
mysqldump -h192.168.128.128 -uroot –p123456 storm TB_RTC_DIM_ORG_DEV>TB_RTC _DIM_ORG_DEV &
導入TB_ RTC _DIM_ORG_DEV至另一個數據庫中
source命令每次執行都會覆蓋(若TB_RTC_DIM_ORG_DEV表存在)
source /home/robinjun/data/ TB_ RTC _DIM_ORG_DEV
5 mysql shell模式導入導出數據命令
應用場景:INSERT...SELECT...和 CREATE TABLE...SELECT...語句,可能會阻止對源表的併發更新,造成對源表鎖的等待。如果查詢比較複雜的話,會造成嚴重的性能問題,我們在應用中應儘量避免使用。實際上,MySQL將這種SQL叫作不確定(non-deterministic)的SQL,不推薦使用。
腳本示例:
#!/bin/bash
while true
do
//從表導出至文件
mysql –h192.168.128.128 -uroot –p123456 -N –e"SELECT * FROM storm.tb_rtc_data" >/data01/mysql01/data/ tb_rtc_data
//從文件導入至表
mysql -h192.168.128.128 -uroot -p123456 -N –e "load data infile '/data01/mysql01/data/tb_rtc_data ' into table storm.tb_rtc_dm_data_5_secfields terminated by '#' "
rm /data01/mysql01/data/tb_rtc_data
//休眠4s
sleep 4
done