http://dba.stackexchange.com/questions/30021/mysql-tree-hierarchical-query

 
 
No problem. We won't show you that ad again. Why didn't you like it?

  • Uninteresting
  • Misleading
  • Offensive
  • Repetitive
  • Other

Oops! I didn't mean to do this.

         up vote13down votefavorite

7

SUB-TREE WITHIN A TREE in MySQL

In my MYSQL Database COMPANY, I have a Table: Employee with recursive association, an employee can be boss of other employee. A self relationship of kind (SuperVisor (1)- SuperVisee (∞) ).

Query to Create Table:

CREATE TABLE IF NOT EXISTS `Employee` (
`SSN` varchar(64) NOT NULL,
`Name` varchar(64) DEFAULT NULL,
`Designation` varchar(128) NOT NULL,
`MSSN` varchar(64) NOT NULL,
PRIMARY KEY (`SSN`),
CONSTRAINT `FK_Manager_Employee`
FOREIGN KEY (`MSSN`) REFERENCES Employee(SSN)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

I have inserted a set of tuples (Query):

INSERT INTO Employee VALUES
("1", "A", "OWNER", "1"), ("2", "B", "BOSS", "1"), # Employees under OWNER
("3", "F", "BOSS", "1"), ("4", "C", "BOSS", "2"), # Employees under B
("5", "H", "BOSS", "2"),
("6", "L", "WORKER", "2"),
("7", "I", "BOSS", "2"),
# Remaining Leaf nodes
("8", "K", "WORKER", "3"), # Employee under F ("9", "J", "WORKER", "7"), # Employee under I ("10","G", "WORKER", "5"), # Employee under H ("11","D", "WORKER", "4"), # Employee under C
("12","E", "WORKER", "4")

The inserted rows has following Tree-Hierarchical-Relationship:

         A     <---ROOT-OWNER
/|\
/ A \
B F
//| \ \
// | \ K
/ | | \
I L H C
/ | / \
J G D E

I written a query to find relationship:

SELECT  SUPERVISOR.name AS SuperVisor,
GROUP_CONCAT(SUPERVISEE.name ORDER BY SUPERVISEE.name ) AS SuperVisee,
COUNT(*)
FROM Employee AS SUPERVISOR
INNER JOIN Employee SUPERVISEE ON SUPERVISOR.SSN = SUPERVISEE.MSSN
GROUP BY SuperVisor;

And output is:

+------------+------------+----------+
| SuperVisor | SuperVisee | COUNT(*) |
+------------+------------+----------+
| A | A,B,F | 3 |
| B | C,H,I,L | 4 |
| C | D,E | 2 |
| F | K | 1 |
| H | G | 1 |
| I | J | 1 |
+------------+------------+----------+
6 rows in set (0.00 sec)

[QUESTION] Instead of complete Hierarchical Tree, I need a SUB-TREE from a point (selective) e.g.: If input argument is B then output should be as below...

+------------+------------+----------+
| SuperVisor | SuperVisee | COUNT(*) |
+------------+------------+----------+
| B | C,H,I,L | 4 |
| C | D,E | 2 |
| H | G | 1 |
| I | J | 1 |
+------------+------------+----------+

Please help me on this. If not query, a stored-procedure can be helpful. I tried, but all efforts were useless!

        asked Dec 6 '12 at 15:36    
Grijesh Chauhan

2862413        

migrated from stackoverflow.com Dec 8 '12 at 9:42

This question came from our site for professional and enthusiast programmers.

 
1                                                                                  
Sample test fiddle                     – mellamokb                 Dec 6 '12 at 15:46                                                                            
                                                                                                                    
I simply provided a test framework for the community to use in exploring this question more easily.                     – mellamokb                 Dec 6 '12 at 15:50                                                                            
                                                                                                                    
@mellamokb  Thanks mellamokb ! :)                     – Grijesh Chauhan                 Dec 6 '12 at 15:52                                                                            
1                                                                                  
@GrijeshChauhan let me ask you this: Which is better to make your own visible waves? To throw pebbles into the ocean, or to throw rocks into a small pond? Going straight to the experts is almost certainly going to give you the best answer, and this sort of question is so important (advanced database topics) that we have given it its own site on the network. But I won't stop you from asking it where you like, that's your prerogative. My prerogative is to vote to move it to another site if I think that's where it belongs. :D We both use the network as we see fit in this case :D                     – jcolebrand♦                 Dec 6 '12 at 16:33                                                                            
1                                                                                  
@jcolebrand: Actually it was my fault only. I use to post question on multiple sides to get a better, quick  and many response. It my experience I always got better answer from expert sides. And I think it was better decision to move question to  Database Administrators. In all the cases, I am very thankful to stackoverflow and  peoples who are active here. I really got solution for many problem that was very tough to find myself or any other web.                     – Grijesh Chauhan                 Dec 6 '12 at 16:43                                                                            
 |              show 11 more comments        

2 Answers                                 2

active         oldest         votes
         up vote2down voteaccepted

I already addressed something of this nature using Stored Procedures : Find highest level of a hierarchical field: with vs without CTEs (Oct 24, 2011)

If you look in my post, you could use the GetAncestry and GetFamilyTree functions as a model for traversing the tree from any given point.

UPDATE 2012-12-11 12:11 EDT

I looked back at my code from my post. I wrote up the Stored Function for you:

DELIMITER $$

DROP FUNCTION IF EXISTS `cte_test`.`GetFamilyTree` $$
CREATE FUNCTION `cte_test`.`GetFamilyTree`(GivenName varchar(64))
RETURNS varchar(1024) CHARSET latin1
DETERMINISTIC
BEGIN DECLARE rv,q,queue,queue_children,queue_names VARCHAR(1024);
DECLARE queue_length,pos INT;
DECLARE GivenSSN,front_ssn VARCHAR(64); SET rv = ''; SELECT SSN INTO GivenSSN
FROM Employee
WHERE name = GivenName
AND Designation <> 'OWNER';
IF ISNULL(GivenSSN) THEN
RETURN ev;
END IF; SET queue = GivenSSN;
SET queue_length = 1; WHILE queue_length > 0 DO
IF queue_length = 1 THEN
SET front_ssn = queue;
SET queue = '';
ELSE
SET pos = LOCATE(',',queue);
SET front_ssn = LEFT(queue,pos - 1);
SET q = SUBSTR(queue,pos + 1);
SET queue = q;
END IF;
SET queue_length = queue_length - 1;
SELECT IFNULL(qc,'') INTO queue_children
FROM
(
SELECT GROUP_CONCAT(SSN) qc FROM Employee
WHERE MSSN = front_ssn AND Designation <> 'OWNER'
) A;
SELECT IFNULL(qc,'') INTO queue_names
FROM
(
SELECT GROUP_CONCAT(name) qc FROM Employee
WHERE MSSN = front_ssn AND Designation <> 'OWNER'
) A;
IF LENGTH(queue_children) = 0 THEN
IF LENGTH(queue) = 0 THEN
SET queue_length = 0;
END IF;
ELSE
IF LENGTH(rv) = 0 THEN
SET rv = queue_names;
ELSE
SET rv = CONCAT(rv,',',queue_names);
END IF;
IF LENGTH(queue) = 0 THEN
SET queue = queue_children;
ELSE
SET queue = CONCAT(queue,',',queue_children);
END IF;
SET queue_length = LENGTH(queue) - LENGTH(REPLACE(queue,',','')) + 1;
END IF;
END WHILE; RETURN rv; END $$

It actually works. Here is a sample:

mysql> SELECT name,GetFamilyTree(name) FamilyTree
-> FROM Employee WHERE Designation <> 'OWNER';
+------+-----------------------+
| name | FamilyTree |
+------+-----------------------+
| A | B,F,C,H,L,I,K,D,E,G,J |
| G | |
| D | |
| E | |
| B | C,H,L,I,D,E,G,J |
| F | K |
| C | D,E |
| H | G |
| L | |
| I | J |
| K | |
| J | |
+------+-----------------------+
12 rows in set (0.36 sec) mysql>

There is only one catch. I added one extra row for the owner

  • The owner has SSN 0
  • The owner is his own boss with MSSN 0

Here is the data

mysql> select * from Employee;
+-----+------+-------------+------+
| SSN | Name | Designation | MSSN |
+-----+------+-------------+------+
| 0 | A | OWNER | 0 |
| 1 | A | BOSS | 0 |
| 10 | G | WORKER | 5 |
| 11 | D | WORKER | 4 |
| 12 | E | WORKER | 4 |
| 2 | B | BOSS | 1 |
| 3 | F | BOSS | 1 |
| 4 | C | BOSS | 2 |
| 5 | H | BOSS | 2 |
| 6 | L | WORKER | 2 |
| 7 | I | BOSS | 2 |
| 8 | K | WORKER | 3 |
| 9 | J | WORKER | 7 |
+-----+------+-------------+------+
13 rows in set (0.00 sec) mysql>
        answered Dec 10 '12 at 20:09    
RolandoMySQLDBA

102k13131263        
 
                                                                                                                    
Excellent ...Thanks A Lots!                     – Grijesh Chauhan                 Dec 12 '12 at 9:11                                                                            
                                                                                                                    
understood the Idea!                     – Grijesh Chauhan                 Dec 12 '12 at 9:15                                                                            
add a comment |                      
 
No problem. We won't show you that ad again. Why didn't you like it?

  • Uninteresting
  • Misleading
  • Offensive
  • Repetitive
  • Other

Oops! I didn't mean to do this.

         up vote2down vote

What you are using is called Adjacency List Model. It has a lot of limitations. You'll be problem when you want to delete/insert a node at a specific place. Its better you use Nested Set Model.

There is a detailed explanation. Unfortunately the article on mysql.com is does not exist any more.

        answered Dec 6 '12 at 15:46    
Shiplu

1213        
 
5                                                                                  
"it has a lot of limitations" - but only when using MySQL. Nearly all DBMS support recursive queries (MySQL is one of the very few that doesn't) and that makes the model really easy to deal with.                     – a_horse_with_no_name                 Dec 7 '12 at 7:05                                                                            
                                                                                                                    
@a_horse_with_no_name Never used anything other than MySQL. So I never knew it. Thanks for the information.                     – Shiplu                 Dec 7 '12 at 11:15                                                                            
add a comment |                      

protected by RolandoMySQLDBA Dec 11 '12 at 18:38

Thank you for your interest in this question.  Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?

MySQL: Tree-Hierarchical query的更多相关文章

  1. Mysql错误:Ignoring query to other database解决方法

    Mysql错误:Ignoring query to other database解决方法 今天登陆mysql show databases出现Ignoring query to other datab ...

  2. mysql中slow query log慢日志查询分析

    在mysql中slow query log是一个非常重要的功能,我们可以开启mysql的slow query log功能,这样就可以分析每条sql执行的状态与性能从而进行优化了. 一.慢查询日志 配置 ...

  3. Error NO.2013 Lost connection to Mysql server during query

    系统:[root@hank-yoon ~]# cat /etc/redhat-release CentOS release 6.3 (Final) DB版本:mysql> select @@ve ...

  4. MySQL查询过程中出现lost connection to mysql server during query 的解决办法

    window7 64位系统,MySQL5.7 问题:在使用shell进行数据表更新操作的过程,输入以下查询语句: ,; 被查询的表记录数达到500W条,在查询过程中出现如题目所示的问题,提示" ...

  5. MySQL5.1升级5.6后,执行grant出错:ERROR 2013 (HY000): Lost connection to MySQL server during query【转载】

    转载: MySQL5.5升级5.6后,执行grant出错:ERROR 2013 (HY000): Lost connection to -mysql教程-数据库-壹聚教程网http://www.111 ...

  6. Procedure execution failed 2013 - Lost connection to MySQL server during query

    1 错误描述 Procedure execution failed 2013 - Lost connection to MySQL server during query 2 错误原因 由错误描述可知 ...

  7. MySQL中查询时"Lost connection to MySQL server during query"报错的解决方案

    一.问题描述: mysql数据库查询时,遇到下面的报错信息: 二.原因分析: dw_user 表数据量比较大,直接查询速度慢,容易"卡死",导致数据库自动连接超时.... 三.解决 ...

  8. Lost connection to MySQL server during query,MySQL设置session,global变量及网络IO与索引

    Navicat导出百万级数据时,报错:2013 - Lost connection to MySQL server during query 网上一番搜索,修改mysql如下几处配置文件即可: sel ...

  9. 解决Lost connection to MySQL server during query错误方法

    昨天使用Navicat for MySQL导入MySQL数据库的时候,出现了一个严重的错误,Lost connection to MySQL server during query,字面意思就是在查询 ...

  10. mysqldump导出报错"mysqldump: Error 2013: Lost connection to MySQL server during query when dumping table `file_storage` at row: 29"

    今天mysql备份的crontab自动运行的时候,出现了报警,报警内容如下 mysqldump: Error 2013: Lost connection to MySQL server during ...

随机推荐

  1. js 把url参数转对象

    //注意url中要含? function getParameterByName(name, url) {            if (!url) {                url = win ...

  2. java 堆栈分析3

    很多方式,比如jconsole.jvisualvm,或者jstack -as 这样的形式, 都可以看到实时的java堆栈的变化: eden suvirried0 suvirried1 old perg ...

  3. 知方可补不足~Sqlserver发布订阅与sql事务的关系

    回到目录 前几讲说了一下通过sqlserver的发布与订阅来实现数据的同步,再通过EF这个ORM架构最终实现架构系统的读写分离,而在使用发布与订阅来实现数据同步时,需要我们注意几点,那就是当操作被使用 ...

  4. Fiddler (六) 最常用的快捷键

    使用QuickExec Fiddler2成了网页调试必备的工具,抓包看数据.Fiddler2自带命令行控制,并提供以下用法. Fiddler的快捷命令框让你快速的输入脚本命令. 键盘快捷键 按ALT+ ...

  5. salesforce 零基础学习(三十二)通过Streams和DOM方式读写XML

    有的时候我们需要对XML进行读写操作,常用的XML操作主要有Streams和DOM方式. 一.Streams方式 Streams常用到的类主要有两个XmlStreamReader 以及XmlStrea ...

  6. salesforce 零基础学习(三十)工具篇:Debug Log小工具

    开发中查看log日志是必不可少的,salesforce自带的效果显示效果不佳,大概显示效果如下所示: chrome商城提供了apex debug log良好的插件,使debug log信息更好显示.假 ...

  7. 贪心算法-最小生成树Kruskal算法和Prim算法

    Kruskal算法: 不断地选择未被选中的边中权重最轻且不会形成环的一条. 简单的理解: 不停地循环,每一次都寻找两个顶点,这两个顶点不在同一个真子集里,且边上的权值最小. 把找到的这两个顶点联合起来 ...

  8. 快速入门系列--WCF--04元数据和异常处理

    本章节将进行元数据和异常处理的介绍,这部分内容概念型比较强,可以快速浏览一下就好. 客户端和服务器借助于终结点进行通信,服务的提供者通过一个或者多个终结点将服务发布出来,服务的消费者则通过创建与之匹配 ...

  9. 数据可视化(8)--D3数据的更新及动画

    最近项目组加班比较严重,D3的博客就一拖再拖,今天终于不用加班了,赶紧抽点时间写完~~ 今天就将D3数据的更新及动画写一写~~ 接着之前的博客写~~ 之前写了一个散点图的例子,下面可以自己写一个柱状图 ...

  10. Advice for students of machine learning--转

    原文地址:http://www.mimno.org/articles/ml-learn/ written by david mimno One of my students recently aske ...