查找parent and childs及其childs的层级树 - MySQL 查询
Find the hierarchy tree of parent and childs and their childs - MySQL Query
我有一个 table,具有不同的区域名称以及 ID 和它们的父 ID。我想生成具有层次结构的报告。如下所示。
Table:群组
ID Name ParentID
1 Corporate NULL
2 Zone 1 1
3 Zone 2 1
4 Zone 3 1
5 Zone 4 1
6 Telangana 2
7 Hyderabad 6
8 Khammam 6
9 Odisha 3
10 Bhubaneshwar 9
使用以上 table 现在我想生成报告。如果我 select 公司那么我需要获取所有数据。如果我 select 区域 1 我需要将所有子关系设置为 well.Like Below
1 区、特伦甘纳邦、海得拉巴、Khammam
请帮我写查询。
在 SQL 中处理分层数据很棘手。我建议您使用 nested sets model 并修改您的 table:添加 left
和 right
列。在添加、更新和删除数据时更新它们(这是简单 SELECT 的代价)。当您这样做时,获取记录 #2 的所有子项将很容易:
SELECT `left`, `right` FROM `table` WHERE id=2;
-- here we get $left and $right
SELECT * FROM `table` WHERE `left`>=$left AND `right` <= $right;
我找到了上述问题的答案。这可以通过使用存储过程来实现。
DELIMITER $$
DROP PROCEDURE IF EXISTS getHierarchy_proc $$
CREATE PROCEDURE getHierarchy_proc (IN GivenID INT, OUT ids VARCHAR(10000))
BEGIN
DECLARE int_check VARCHAR(1000);
DECLARE is_exit TINYINT(1) DEFAULT 0;
DROP TABLE IF EXISTS bu_tmp;
CREATE TEMPORARY TABLE bu_tmp(
bu_id INT(11) NOT NULL,
is_upd TINYINT(1) NOT NULL DEFAULT 0);
SET SESSION GROUP_CONCAT_MAX_LEN = 100000;
INSERT INTO bu_tmp (bu_id)
SELECT GivenID;
SET int_check = (SELECT bu_id FROM bu_tmp WHERE bu_id = GivenID AND is_upd = 0);
SET is_exit = 1;
REPEAT
IF is_exit > 0 THEN
INSERT INTO bu_tmp (bu_id,is_upd)
SELECT ID,0 FROM Groups WHERE FIND_IN_SET(parent_id , int_check);
UPDATE bu_tmp SET is_upd = 1 WHERE FIND_IN_SET(bu_id,int_check);
SET is_exit = (SELECT COUNT(*) FROM bu_tmp WHERE is_upd = 0);
SET int_check = (SELECT GROUP_CONCAT(bu_id) FROM bu_tmp WHERE is_upd = 0);
END IF;
UNTIL is_exit = 0 END REPEAT;
SET ids = (SELECT GROUP_CONCAT(lew.le_wh_id)
FROM bu_tmp bu JOIN legalentity_warehouses lew
WHERE bu.bu_id = lew.bu_id
AND lew.dc_type = 118001
AND lew.status = 1);
END$$
DELIMITER ;
我有一个 table,具有不同的区域名称以及 ID 和它们的父 ID。我想生成具有层次结构的报告。如下所示。
Table:群组
ID Name ParentID
1 Corporate NULL
2 Zone 1 1
3 Zone 2 1
4 Zone 3 1
5 Zone 4 1
6 Telangana 2
7 Hyderabad 6
8 Khammam 6
9 Odisha 3
10 Bhubaneshwar 9
使用以上 table 现在我想生成报告。如果我 select 公司那么我需要获取所有数据。如果我 select 区域 1 我需要将所有子关系设置为 well.Like Below
1 区、特伦甘纳邦、海得拉巴、Khammam
请帮我写查询。
在 SQL 中处理分层数据很棘手。我建议您使用 nested sets model 并修改您的 table:添加 left
和 right
列。在添加、更新和删除数据时更新它们(这是简单 SELECT 的代价)。当您这样做时,获取记录 #2 的所有子项将很容易:
SELECT `left`, `right` FROM `table` WHERE id=2;
-- here we get $left and $right
SELECT * FROM `table` WHERE `left`>=$left AND `right` <= $right;
我找到了上述问题的答案。这可以通过使用存储过程来实现。
DELIMITER $$
DROP PROCEDURE IF EXISTS getHierarchy_proc $$
CREATE PROCEDURE getHierarchy_proc (IN GivenID INT, OUT ids VARCHAR(10000))
BEGIN
DECLARE int_check VARCHAR(1000);
DECLARE is_exit TINYINT(1) DEFAULT 0;
DROP TABLE IF EXISTS bu_tmp;
CREATE TEMPORARY TABLE bu_tmp(
bu_id INT(11) NOT NULL,
is_upd TINYINT(1) NOT NULL DEFAULT 0);
SET SESSION GROUP_CONCAT_MAX_LEN = 100000;
INSERT INTO bu_tmp (bu_id)
SELECT GivenID;
SET int_check = (SELECT bu_id FROM bu_tmp WHERE bu_id = GivenID AND is_upd = 0);
SET is_exit = 1;
REPEAT
IF is_exit > 0 THEN
INSERT INTO bu_tmp (bu_id,is_upd)
SELECT ID,0 FROM Groups WHERE FIND_IN_SET(parent_id , int_check);
UPDATE bu_tmp SET is_upd = 1 WHERE FIND_IN_SET(bu_id,int_check);
SET is_exit = (SELECT COUNT(*) FROM bu_tmp WHERE is_upd = 0);
SET int_check = (SELECT GROUP_CONCAT(bu_id) FROM bu_tmp WHERE is_upd = 0);
END IF;
UNTIL is_exit = 0 END REPEAT;
SET ids = (SELECT GROUP_CONCAT(lew.le_wh_id)
FROM bu_tmp bu JOIN legalentity_warehouses lew
WHERE bu.bu_id = lew.bu_id
AND lew.dc_type = 118001
AND lew.status = 1);
END$$
DELIMITER ;