MYSQL函數編寫一

需求表以下:java


單純的用mysql函數來表達上述關係:node

DELIMITER $$
USE `euht`$$
DROP FUNCTION IF EXISTS `queryCurrentAlarmChildren`$$
CREATE DEFINER=`root`@`%` FUNCTION `queryCurrentAlarmChildren`(nodeId CHAR(255),treeLevel CHAR(255)) RETURNS VARCHAR(4000) CHARSET utf8
BEGIN
DECLARE sNodeId VARCHAR(255);
DECLARE sCurrentAlarmId VARCHAR(8000);
DECLARE sTreeLevel VARCHAR(255);
DECLARE sTempLine VARCHAR(4000);
DECLARE sTempEdu VARCHAR(4000);
DECLARE sTempEbu VARCHAR(4000);
DECLARE sWhileInt INT;
DECLARE sWhileTotal INT;
DECLARE sWhileGroupConcat VARCHAR(1024);
DECLARE sWhileConcat VARCHAR(4000);
DECLARE sWhileTempValue INT;
SET sNodeId = CAST(nodeId AS CHAR);
SET sTreeLevel = CAST(treeLevel AS CHAR);
SET sCurrentAlarmId = '$';
SET sTempLine = '';
SET sTempEdu = '';
SET sTempEbu = '';
SET sWhileInt = 0;
SET sWhileTotal = 0;
SET sWhileConcat = '';
IF sTreeLevel='3' THEN 
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE device_id = sNodeId;
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE device_id = sNodeId ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
ELSEIF sTreeLevel='2' THEN
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE device_id = sNodeId;
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE device_id = sNodeId ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
	SELECT COUNT(id) INTO sWhileTotal FROM cap_ebu WHERE edu_id = sNodeId;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM cap_ebu WHERE edu_id = sNodeId ORDER BY add_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sTempEbu = CONCAT(sTempEbu,',',IFNULL(sWhileConcat,''));
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEbu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEbu)>0 ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
ELSEIF	sTreeLevel='1' THEN
	SELECT COUNT(*) INTO sWhileTotal FROM cap_edu WHERE line_id = sNodeId;
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM cap_edu WHERE line_id = sNodeId LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sTempEdu = CONCAT(sTempEdu,',',IFNULL(sWhileConcat,''));	
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEdu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEdu)>0 ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
	SELECT COUNT(id) INTO sWhileTotal FROM cap_ebu WHERE FIND_IN_SET(edu_id,sTempEdu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM cap_ebu WHERE FIND_IN_SET(edu_id,sTempEdu)>0 ORDER BY add_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sTempEbu = CONCAT(sTempEbu,',',IFNULL(sWhileConcat,''));
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEbu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEbu)>0 ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
ELSE
	SELECT GROUP_CONCAT(id) INTO sTempLine FROM train_line WHERE parent_id = sNodeId;
	SELECT COUNT(*) INTO sWhileTotal FROM cap_edu WHERE FIND_IN_SET (line_id,IFNULL(sTempLine,''))>0;
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM cap_edu WHERE FIND_IN_SET(line_id,sTempLine)>0 LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sTempEdu = CONCAT(sTempEdu,',',IFNULL(sWhileConcat,''));	
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEdu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEdu)>0 ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
	SELECT COUNT(id) INTO sWhileTotal FROM cap_ebu WHERE FIND_IN_SET(edu_id,sTempEdu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM cap_ebu WHERE FIND_IN_SET(edu_id,sTempEdu)>0 ORDER BY add_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sTempEbu = CONCAT(sTempEbu,',',IFNULL(sWhileConcat,''));
	SELECT COUNT(id) INTO sWhileTotal FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEbu)>0;
	SET sWhileInt = 0;
	SET sWhileConcat = '';
	WHILE sWhileTotal >= (sWhileInt*20) DO
		SET sWhileTempValue = sWhileInt*20;
		SELECT GROUP_CONCAT(id) INTO sWhileGroupConcat FROM current_alarm WHERE FIND_IN_SET(device_id,sTempEbu)>0 ORDER BY ceate_time DESC LIMIT sWhileTempValue,20;
		SET sWhileConcat = CONCAT(sWhileConcat,',',IFNULL(sWhileGroupConcat,''));
		SET sWhileInt = sWhileInt + 1;
	END WHILE;
	SET sCurrentAlarmId = CONCAT(sCurrentAlarmId,',',IFNULL(sWhileConcat,''));
END IF;
RETURN sCurrentAlarmId;
END$$
DELIMITER ;

SELECT * FROM current_alarm WHERE FIND_IN_SET(id,queryCurrentAlarmChildren('22fd52a51efb4401b091f944e2051a89','0'))>0;


注意:mysql

編寫函數的時候,須要注意幾個地方:sql

  1.     使用「GROUP_CONCAT」函數時,可以拼接的最大長度是1kb(1024字節)。不然,超過部分將會忽略。函數

        考慮到這個緣由,寫函數時,經過分頁的思路來進行分段拼接。spa

  2.     使用「GROUP_CONCAT」函數時,若是拼接的來源爲零,則拼接的結果爲null;如code

        SELECT GROUP_CONCAT(id) FROM aform WHERE id = '11' ;(不存在id爲11的行),執行的結果爲null。orm

  3.    使用「CONCAT」函數時,若是存在爲null值,則拼接結果爲null。如:form

       SELECT CONCAT('1',',',NULL);執行結果爲nullclass

       SELECT CONCAT(NULL,',','2');執行結果爲null

  4.   當「DECLARE 」申明瞭一個變量,而沒給該變量初始化時,其默認爲null,這裏只驗證了VARCHAR類型。


後記:上面這種方法能解決需求中問題,但是查詢效率極慢,沒法忍受。下面這種方法效率獲得極大提升。

由於頁面會提供兩個參數給後臺:一個參數是nodeId(當前點擊的id),另外一個參數是level(樹等級)。

根據level等級來判斷執行那個查詢語句。

例如:level爲0或-1(表明全網),則執行如下查詢語句:


SELECT * FROM
    (SELECT * FROM euht.HISTORY_ALARM ha WHERE ha.DEVICE_ID = 
    (SELECT ceb.ID FROM euht.CAP_EBU ceb WHERE ha.DEVICE_ID = ceb.ID AND ceb.EDU_ID = 
        (SELECT ced.id FROM euht.CAP_EDU ced WHERE ceb.EDU_ID = ced.ID AND ced.LINE_ID = 
                (SELECT tl.ID FROM euht.TRAIN_LINE tl WHERE tl.PARENT_ID = ? AND tl.ID = ced.LINE_ID)))
    UNION ALL
    (SELECT * FROM euht.HISTORY_ALARM ha WHERE ha.DEVICE_ID = 
        (SELECT ced.id FROM euht.CAP_EDU ced WHERE ha.DEVICE_ID = ced.ID AND ced.LINE_ID = 
                (SELECT tl.ID FROM euht.TRAIN_LINE tl WHERE tl.PARENT_ID = ? AND tl.ID = ced.LINE_ID)))) t LIMIT 0,15


若是level爲1(表明京津高鐵這一等級),則執行如下查詢語句:

                SELECT
			*
			FROM HISTORY_ALARM ha WHERE ha.DEVICE_ID = 
	    	(SELECT ceb.ID FROM CAP_EBU ceb WHERE ha.DEVICE_ID = ceb.ID AND ceb.EDU_ID = 
	        (SELECT ced.id FROM CAP_EDU ced WHERE ceb.EDU_ID = ced.ID AND ced.LINE_ID = #{nodeId,jdbcType=VARCHAR}))
	        UNION ALL
	        SELECT
			*
	        FROM HISTORY_ALARM ha WHERE ha.DEVICE_ID = 
	        (SELECT ced.id FROM CAP_EDU ced WHERE ha.DEVICE_ID = ced.ID AND ced.LINE_ID = #{nodeId,jdbcType=VARCHAR})


若是level爲2(表明EDU這一等級),則執行如下查詢語句:

SELECT
			*
			FROM HISTORY_ALARM ha WHERE ha.DEVICE_ID = 
	    	(SELECT ceb.ID FROM CAP_EBU ceb WHERE ha.DEVICE_ID = ceb.ID AND ceb.EDU_ID = #{nodeId,jdbcType=VARCHAR})
	        UNION ALL
	        SELECT
			*
	        FROM HISTORY_ALARM ha WHERE ha.DEVICE_ID = #{nodeId,jdbcType=VARCHAR}


若是level爲3(表明EBU這一等級),則執行如下查詢語句:

SELECT
			*
	        FROM HISTORY_ALARM ha WHERE ha.DEVICE_ID = #{nodeId,jdbcType=VARCHAR}
相關文章
相關標籤/搜索