1. 程式人生 > >MySQL選單父子表排序

MySQL選單父子表排序

當開發系統時,在MySQL中,我們設計的選單表 包括選單ID ,父級ID,和選單排序 這個三個欄位時,正常查詢時,order by 選單ID  即可,然而當我們新增之前已有選單的子選單時,選單ID又是自增長型別的,此時查詢出來的結果的排序就不是我們想要的的了。以下是一張sys_menu選單表:

CREATE TABLE `sys_menu` (
  `MENU_ID` int(11) NOT NULL AUTO_INCREMENT COMMENT '選單ID',
  `MENU_NAME` varchar(255) DEFAULT NULL COMMENT '選單名稱',
  `MENU_URL` varchar(255) DEFAULT NULL COMMENT '選單地址',
  `PARENT_ID` varchar(100) DEFAULT NULL COMMENT '父級ID',
  `MENU_ORDER` varchar(100) DEFAULT NULL COMMENT '選單順序',
  `MENU_ICON` varchar(30) DEFAULT NULL COMMENT '選單圖示',
  `MENU_TYPE` varchar(10) DEFAULT NULL COMMENT '選單型別',
  PRIMARY KEY (`MENU_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8 COMMENT='*系統選單表';

INSERT INTO `sys_menu` VALUES ('1', '系統字典', '#', '0', '1', 'fa-desktop', '2');
INSERT INTO `sys_menu` VALUES ('2', '字典型別', 'role.do', '1', '2', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('4', '字典名稱', 'happuser/listUsers.do', '1', '4', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('5', '系統使用者', 'user/listUsers.do', '1', '3', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('6', '選單管理', '#', '0', '2', 'fa-list', '2');
INSERT INTO `sys_menu` VALUES ('7', '選單維護', 'ez/system/sysmenu/list.do', '6', '1', 'fa-caret-right', '2');
INSERT INTO `sys_menu` VALUES ('8', '效能監控', 'druid/index.html', '9', '1', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('9', '系統工具', '#', '0', '3', 'fa-th', '1');
INSERT INTO `sys_menu` VALUES ('10', '介面測試', 'tool/interfaceTest.do', '9', '2', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('11', '傳送郵件', 'tool/goSendEmail.do', '9', '3', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('12', '置二維碼', 'tool/goTwoDimensionCode.do', '9', '4', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('13', '多級別樹', 'tool/ztree.do', '9', '5', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('14', '地圖工具', 'tool/map.do', '9', '6', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('15', '微信管理', '#', '0', '2', 'fa-comments', '2');
INSERT INTO `sys_menu` VALUES ('16', '文本回復', 'textmsg/list.do', '15', '2', 'fa-caret-right', '2');
INSERT INTO `sys_menu` VALUES ('17', '應用命令', 'command/list.do', '15', '4', 'fa-caret-right', '2');
INSERT INTO `sys_menu` VALUES ('18', '圖文回覆', 'imgmsg/list.do', '15', '3', 'fa-caret-right', '2');
INSERT INTO `sys_menu` VALUES ('19', '關注回覆', '#', '15', '1', 'fa-caret-right', '2');
INSERT INTO `sys_menu` VALUES ('20', '線上管理', 'onlinemanager/list.do', '1', '5', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('21', '列印測試', 'tool/printTest.do', '9', '7', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('22', '客戶管理', 'sdfsdf/index.do', '1', '1', 'fa-caret-right', '1');
INSERT INTO `sys_menu` VALUES ('23', '選單管理', 'ez/system/sysmenu/list.html', '19', '1', 'fa-leaf green', '2');
INSERT INTO `sys_menu` VALUES ('24', '三級1', '#', '19', '2', 'fa-pencil', '2');

參考:http://stackoverflow.com/questions/14890204/order-sql-tree-hierarchy 上給了答案,但是我的業務比他多MENU_ORDER 的一個欄位,顧,我在他答案的基礎上加以改造,現將整理如下:

第一步:建立一個函式,我用的Navicat for mysql 工具,點選查詢,輸入如下程式碼:

CREATE FUNCTION getPriority (inID INT) RETURNS VARCHAR(255) DETERMINISTIC
  begin
    DECLARE gParentID INT DEFAULT 0;
    DECLARE gOderID INT DEFAULT 0;
    DECLARE gPriority VARCHAR(255) DEFAULT '';
   
    SELECT PARENT_ID,MENU_ORDER INTO gParentID,gOderID FROM sys_menu WHERE MENU_ID = inID;

    if gParentID > 0 then 
	SET gPriority = CONCAT(gOderID,inID);
    else 
	SET gPriority = inID;
    end if;		
		 
    WHILE gParentID > 0 DO  /*0為根*/
      SET gPriority = CONCAT(gParentID, '.', gPriority);
      SELECT PARENT_ID INTO gParentID FROM sys_menu WHERE MENU_ID = gParentID;
    END WHILE; 
    RETURN gPriority;
  end

點選執行之後,就會出現如下資訊,點選函式就會出現剛剛建立的函式,如果沒有顯示,點選右鍵重新整理一下就會顯示出來。

第二步:執行一下函式,就會得到你想要的結果,注意,MENU_ID 為資料庫欄位名。

SELECT  *  FROM  sys_menu  ORDER BY  getPriority(MENU_ID)