0

Helllo,

My database table structure is as below.

TableName:- UserTable

id | empName | reportsTo
-----------------------
1  | XYZ     | -
2  | ABC     | 1
3  | MNP     | 2
4  | IJK     | 3
5  | PQR     | 4
6  | DEF     | 3
7  | STU     | 2

How can I get the details of user he reports to in top hierarchy.

Eg. When I select user whose id is 7 the output should be

id    empName  reportsTo
2     ABC      1
1     XYZ      -

same way when I select user whose id is 6 it should return data of id's 3,2,1.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
Talk2Nit
  • 1,115
  • 3
  • 22
  • 38

2 Answers2

0

There's a temporary solution but NOT GOOD to continue using it. You have to drop your table and create new organized one

First count different reportsto values

SELECT COUNT(DISTINCT reportsto) FROM test

You will get a number. let's suppose you get (5) then there're 5 are bosses of some employees

SELECT * FROM test WHERE 
id=(SELECT @boss := reportsto FROM test WHERE id=7) 
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)
OR 
id=(SELECT @boss := reportsto FROM test WHERE id=@boss1)
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)
OR 
id=(SELECT @boss := reportsto FROM test WHERE id=@boss1)

If you get (10) then the query'd be

SELECT * FROM test WHERE 
id=(SELECT @boss := reportsto FROM test WHERE id=7) 
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)
OR 
id=(SELECT @boss := reportsto FROM test WHERE id=@boss1)
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)
OR 
id=(SELECT @boss := reportsto FROM test WHERE id=@boss1)
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)
OR 
id=(SELECT @boss := reportsto FROM test WHERE id=@boss1)
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)
OR 
id=(SELECT @boss := reportsto FROM test WHERE id=@boss1)
OR 
id=(SELECT @boss1 := reportsto FROM test WHERE id=@boss)

.

.

.

and so on

JORDAN MI
  • 78
  • 1
  • 8
0

I don't think you understood the possible duplicate link I posted so here's the solution posted there with some trivial tweaks to suit your data.

drop table if exists usertable;
create table usertable(id int, empName varchar(3), reportsTo int);
insert into usertable values
(1  , 'XYZ'     , null),
(2  , 'ABC'     , 1),
(3  , 'MNP'     , 2),
(4  , 'IJK'     , 3),
(5  , 'PQR'     , 4),
(6  , 'DEF'     , 3),
(7  , 'STU'     , 2);

SELECT T2.id, T2.empname,t2.reportsto
FROM (
    SELECT
        @r AS _id,
        (SELECT @r := reportsto FROM usertable WHERE id = _id) AS parent_id,
        @l := @l + 1 AS lvl
    FROM
        (SELECT @r := 7, @l := 0) vars,
        usertable h
    WHERE @r <> 0) T1
JOIN usertable T2
ON T1._id = T2.id
where t2.id <> 7
ORDER BY T1.lvl;

+------+---------+-----------+
| id   | empname | reportsto |
+------+---------+-----------+
|    2 | ABC     |         1 |
|    1 | XYZ     |      NULL |
+------+---------+-----------+
2 rows in set (0.03 sec)

and for id 6

SELECT T2.id, T2.empname,t2.reportsto
FROM (
    SELECT
        @r AS _id,
        (SELECT @r := reportsto FROM usertable WHERE id = _id) AS parent_id,
        @l := @l + 1 AS lvl
    FROM
        (SELECT @r := 6, @l := 0) vars,
        usertable h
    WHERE @r <> 0) T1
JOIN usertable T2
ON T1._id = T2.id
where t2.id <> 6
ORDER BY T1.lvl; 

+------+---------+-----------+
| id   | empname | reportsto |
+------+---------+-----------+
|    3 | MNP     |         2 |
|    2 | ABC     |         1 |
|    1 | XYZ     |      NULL |
+------+---------+-----------+
3 rows in set (0.00 sec)

Note I have changed reportsto from - to null for id 1. With this only works if reports to is less than id if not you will have to have some serious thought about your data structure.

P.Salmon
  • 17,104
  • 2
  • 12
  • 19