Concatenate values with LEFT join - mysql

While searching, I came across a very similar post here
but I have an additional question to what has been posted there already.
id|person_name|department_name|phone_number
--+-----------+---------------+------------
1 |"John" |"Finance" |"023451"
1 |"John" |"Finance" |"99478"
1 |"John" |"Finance" |"67890"
1 |"John" |"Marketing" |"023451"
1 |"John" |"Marketing" |"99478"
1 |"John" |"Marketing" |"67890"
2 |"Barbara" |"Finance" |""
3 |"Michelle" |"" |"005634"
Lets say I want the final result as:
id|person_name|department_name|phone_number
--+-----------+---------------+------------
1 |"John" |"Finance" |"023451", "99478", "67890"
1 |"John" |"Marketing" |"023451", "99478", "67890"
2 |"Barbara" |"Finance" |""
3 |"Michelle" |"" |"005634"
basically similar results from phone_number concatenated; then can you advise what should I be doing ? I tried GROUP_CONCAT with DISTINCT but it didn't help.

So this will pivot and comma delimit your Numbers which I believe is the desired effect? This is a SQL Server solution
declare #t table (OrderedID int, EmpName varchar(50), EmpDep varchar(50), Num varchar(50))
insert into #t
values
(1,'John','Dep1','123')
,(1,'John','Dep1','456')
,(1,'John','Dep2','789')
,(2,'Doug','Dep1','987')
,(2,'Doug','Dep1','654')
,(2,'Steve','Dep2','321')
Select
*
From #t
SELECT distinct e.EmpName,
e.EmpDep,
LEFT(r.Num , LEN(r.Num)-1) num
FROM #t e
CROSS APPLY
(
SELECT r.Num + ', '
FROM #t r
where e.EmpName = r.EmpName
and e.EmpDep = r.EmpDep
FOR XML PATH('')
) r (Num)
Ouput:
EmpName EmpDep num
Doug Dep1 987, 654
John Dep1 123, 456
John Dep2 789
Steve Dep2 321

Related

MySQL query aggregate MAX and subquery

Is there a way to get value from a subquery in where inside select?
stop_link Table
id | duid | domain_id
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
4 | 2 | 2
5 | 3 | 1
Result that I want (assume domain_id = 2)
duid | domain_id
3 | 2
Query (not working):
INSERT INTO stop_link (
duid,
domain_id)
SELECT
IFNULL(MAX(sl.duid), 0) + 1 AS duid,
sl.domain_id
FROM
stop_link sl
WHERE sl.domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1)
Query working but I wish to avoid the Set Variable:
SET #domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1);
SELECT
IFNULL(MAX(sl.duid), 0) + 1 AS duid
, #domain_id
FROM
stop_link sl
WHERE sl.domain_id = #domain_id;
Do you mean something like this:
/*Your example Table*/
DECLARE #T
TABLE(ID INT,duid INT,domain_id INT)
INSERT INTO #T
VALUES
(1 , 1 , 1 ),
(2 , 2 , 1),
(3 , 1 , 2),
(4 , 2 , 2),
(5 , 3 , 1)
--The query
SELECT domain_id,Isnull(max(duid),0)+1 [newId]
FROM #T
GROUP BY domain_id
No need of max():
SELECT
IFNULL(sl.duid, 0) + 1 AS duid,
sl.domain_id
FROM
stop_link sl
WHERE sl.domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1)
ORDER by sl.id DESC
LIMIT 1
Changed answer based on new info from the comments. It sounds like you've got only_full_group_by enabled in your sql_mode. Your query would probably work with that disabled, but the following may also work for you:
INSERT INTO stop_link (
duid,
domain_id)
SELECT
IFNULL(MAX(sl.duid), 0) + 1 AS duid,
sl.domain_id
FROM
stop_link sl
WHERE sl.domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1)
-- ORDER by sl.domain_id DESC LIMIT 1 # Removed in favor of the following line
GROUP BY sl.domain_id HAVING MAX(sl.id)
;
Note that the subquery may not be returning the stop_domain.id that you want it to be -- you might have intended to select MAX(sd.id), or perhaps you just removed a WHERE sd.url='foo' for clarity's sake.

SQL query to find multiple value from single field with input parameters [duplicate]

This question already has answers here:
Turning a Comma Separated string into individual rows
(16 answers)
Closed 7 years ago.
Is it possible to find multiple values from a single field, that are within a set of input parameters?
The DB example would be something like this
User Login_DT_TM
0001 1/1/2015 12:00, 1/1/2015 12:30,1/6/2015 09:00
0002 1/3/2015 13:00, 1/5/2015 16:00
And i would need something to give me this output
0001 1/1/2015 12:00
0001 1/1/2015 12:30
0002 1/3/2015 13:00
Where login_DT_TM => 1/1/2015 '00:00' AND login_DT_TM =< 1/4/2015 '23:59'
SQL Fiddle
MS SQL Server 2008 Schema Setup:
CREATE TABLE Test_Table ([User] VARCHAR(10) , Login_DT_TM VARCHAR(4000))
INSERT INTO Test_Table VALUES
('0001','1/1/2015 12:00, 1/1/2015 12:30,1/6/2015 09:00'),
('0002','1/3/2015 13:00, 1/5/2015 16:00')
Query 1:
WITH X AS
(
SELECT [User]
,CAST(Split.a.value('.', 'VARCHAR(100)') AS DATETIME) Login_DT_TM
FROM
(SELECT [User]
,Cast ('<X>' + Replace(Login_DT_TM, ',', '</X><X>') + '</X>' AS XML) AS Data
FROM Test_Table
) AS t
CROSS APPLY Data.nodes ('/X') AS Split(a)
)
SELECT [User]
,Login_DT_TM
FROM X
WHERE Login_DT_TM > '20141231'
AND Login_DT_TM < '20150105'
Results:
| User | Login_DT_TM |
|------|---------------------------|
| 0001 | 2015-01-01 12:00:00.000 |
| 0001 | 2015-01-01 12:30:00.000 |
| 0002 | 2015-01-03 13:00:00.000 |
This should meet your expectations:
DECLARE #table TABLE
(
[USER] NVARCHAR(30) ,
LOGIN NVARCHAR(300)
);
INSERT INTO #table
( [USER], LOGIN )
VALUES ( N'0001',
N'1/1/2015 12:00, 1/1/2015 12:30, 1/6/2015 09:00'
),
( N'0002',
N'1/3/2015 13:00, 1/5/2015 16:00'
);
WITH tmp ( userid, part , rest )
AS ( SELECT [USER] ,
CONVERT(NVARCHAR(300),LEFT(LOGIN, CHARINDEX(',', LOGIN + ',') - 1)) ,
CONVERT(NVARCHAR(300),STUFF(LOGIN, 1, CHARINDEX(',', LOGIN + ',')+1, ''))
FROM #table
UNION ALL
SELECT userid ,
CONVERT(NVARCHAR(300),LEFT(rest, CHARINDEX(',', rest + ',') - 1)) ,
CONVERT(NVARCHAR(300),STUFF(rest, 1, CHARINDEX(',', rest + ',')+1, '') )
FROM tmp
WHERE rest > ''
)
SELECT tmp.userid, tmp.part
FROM tmp;

How to select a row with maximum value for a column in MySQL?

*None of other available answers solved my problem
I have a table t like this
id,cc,count
'1','HN','22'
'1','US','18'
'1','VN','1'
'2','DK','2'
'2','US','256'
'3','SK','1'
'3','US','66310'
'4','UA','2'
'4','US','263'
'6','FR','7'
'6','US','84'
'9','BR','3'
I want to get the rows for ids with maximum count, like below:
id,cc,count
'1','HN','22'
'2','US','256'
'3','US','66310'
'4','US','263'
'6','US','84'
'9','BR','3'
My current code is like this but I am not getting the expected results:
SELECT t.* FROM t
JOIN (
SELECT
t.id,t.cc
,max(t.count) as max_slash24_count
FROM t
group by t.id,t.cc
) highest
ON t.count = highest.max_slash24_count
and t.cc = highest.cc
Can anybody help me out?
Remove CC column from group by. Try this.
SELECT t.* FROM t
JOIN (
SELECT
t.id
,max(t.count) as max_slash24_count
FROM t
group by t.id
) highest
ON t.count = highest.max_slash24_count
and t.id= highest.id
Try this:
create table t (id varchar(10), cc varchar(10), count varchar(10))
insert into t (id,cc,count) values ('1','HN','22');
insert into t (id,cc,count) values ('1','US','18');
insert into t (id,cc,count) values ('1','VN','1');
insert into t (id,cc,count) values ('2','DK','2');
insert into t (id,cc,count) values ('2','US','256');
insert into t (id,cc,count) values ('3','SK','1');
insert into t (id,cc,count) values ('3','US','66310');
insert into t (id,cc,count) values ('4','UA','2');
insert into t (id,cc,count) values ('4','US','263');
insert into t (id,cc,count) values ('6','FR','7');
insert into t (id,cc,count) values ('6','US','84');
insert into t (id,cc,count) values ('9','BR','3');
select *
from t
where exists (
select *
from t as t1
group by t1.id
having t1.id = t.id and max(t1.count) = t.count
)
Result
ID CC COUNT
-------------
1 HN 22
2 US 256
3 US 66310
4 US 263
6 US 84
9 BR 3
Check SQLFiddle
This question was answered a lot of times on SO. The query is as simple as this:
SELECT m.id, m.cc, m.count
FROM t m # "m" from "max"
LEFT JOIN t b # "b" from "bigger"
ON m.id = b.id # match a row in "m" with a row in "b" by `id`
AND m.count < b.count # match only rows from "b" having bigger count
WHERE b.count IS NULL # there is no "bigger" count than "max"
The real issue on your question is about the column types. If count is char (and not int) then the string comparison happens using the dictionary order, not the numeric order.
For example, if the third row reads:
'1','VN','123'
you might expect it to be selected in the output, because 123 is bigger than 22. This does not happen because, as string, '123' is smaller than '22'.
Even tho, this was already answered, using ROW_NUMBER functionality as in SQL Server is quite fun and interesting: please look at this query:
SELECT TT.Id, TT.cc, TT.count
FROM (
SELECT t.cc
, t.count
, #row_number:=CASE WHEN #Id=Id THEN #row_number+1 ELSE 1 END AS row_number
, #Id:=Id AS Id
FROM t, (SELECT #row_number:=0, #Id:='') AS temp
ORDER BY t.Id, t.count DESC
) AS TT
WHERE TT.row_number = 1
ORDER BY TT.Id;
It produces expected output:
| Id | cc | count |
|----|----|-------|
| 1 | HN | 22 |
| 2 | US | 256 |
| 3 | US | 66310 |
| 4 | US | 263 |
| 6 | US | 84 |
| 9 | BR | 3 |
SQLFiddle
I've taken test data from #Andrey Morozov

SQL PIVOT QUERY ISSUE

I have a table [dbo].[RISK_DISCPLN]
RISK_DISCPLN_ID RISK_DISCPLN_NM
1 LegalRisk
2 institutional Risk
4 Market Risk
Tabbe Name [dbo].[PROJ_RISK_DISCPLN]
PROJ_ID RISK_DISCPLN_ID
1 1
1 2
1 4
2 1
2 2
2 4
3 1
3 2
3 4
Table Name [dbo].[USER]
USER_ID USER_FIRST_NM USER_LST_NM
2 saravanakumar rajkumar
3 Soosai Antony
4 Adam Allen
5 Babita Tripathy
9 stacey Davis
11 NULL NULL
I tried below query to display names into the corresponding risk, i am getting all the names as null value... Help needed please
;with cte as
(
SELECT [PROJ_RISK_DISCPLN].PROJ_ID,
[USER].USER_LST_NM + ' '+ [USER].USER_FIRST_NM as Name,
[RISK_DISCPLN].RISK_DISCPLN_NM,
[RISK_DISCPLN].RISK_DISCPLN_ID,
[USER].[USER_ID]
FROM dbo.[PROJ_RISK_DISCPLN]
left join [dbo].[USER]
on [PROJ_RISK_DISCPLN].RISK_OWN_USER_ID = [dbo].[USER].[USER_ID]
left join dbo.[RISK_DISCPLN] on
[PROJ_RISK_DISCPLN].RISK_DISCPLN_ID = [RISK_DISCPLN].RISK_DISCPLN_ID
)
select *
from
(
select c1.PROJ_ID,
c1.RISK_DISCPLN_NM,
STUFF(
(SELECT ', ' + c2.Name
FROM cte c2
where c1.PROJ_ID = c2.PROJ_ID
and c1.RISK_DISCPLN_ID = c2.RISK_DISCPLN_ID
FOR XML PATH (''))
, 1, 1, '') AS Name
from cte c1
) d
pivot
(
max(Name)
for RISK_DISCPLN_NM in ([LegalRisk Owner],[institutional Risk Owner],[Market Risk Owner])
) piv
I got answer, Instead [LegalRisk Owner],[institutional Risk Owner],[Market Risk Owner]
i have to use [LegalRisk],[institutional Risk],[Market Risk] ....

SQL Server Query or Tool to show Hierarchical Data

We have a general organizational table structure, think of it s a Tree or Pyramid Hierarchy. We basically have multiple "trees" we want to show. On for one company, one for another ETC.
Does anyone know of a good way to display this data? SQL Query would be nice, doubt it would be possible, but I wouldn't be against using some OTS tool (preferably free). I would also like to avoid some type of report. I don't need an actual solution just need to know if its possible. So if you say SQL if you can give me a 2 table example of showing a root a leave I would be happy.
Structure is pretty general
And each table is linked through a surrogate key CompanyID, CompanyGroupID, etc.
Any suggestions on ways we could display/query for this data? Last resort is to write a quick C# Windows Application...
We would like to see it in tree form:
-- 1-Company
-- / \
-- CompanyGroupA CompanyGroupB
-- / \ \
-- CompanyStoreA1 CompanyStoreA1 CompanyStoreB
-- / \ / \
--Employee A B C
In attempt to please the masses here is an example test script to populate the query.
DECLARE #Company table (id int, name varchar(40) )
INSERT #Company VALUES (1,'Living Things' )
INSERT #Company VALUES (2,'Boring Company' )
DECLARE #CompanyGroup table (id int, name varchar(40), CompanyID int)
INSERT #CompanyGroup VALUES (1,'Pets',1 )
INSERT #CompanyGroup VALUES (2,'Humans',1 )
INSERT #CompanyGroup VALUES (3,'Electronics',2 )
INSERT #CompanyGroup VALUES (4,'Food',2 )
DECLARE #CompanyStore table (id int, name varchar(40), CompanyGroupID int)
INSERT #CompanyStore VALUES (1,'PetsStoreA',1 )
INSERT #CompanyStore VALUES (2,'PetsStoreB',1 )
INSERT #CompanyStore VALUES (3,'PetsStoreC',1 )
INSERT #CompanyStore VALUES (4,'PetsStoreD', 1)
INSERT #CompanyStore VALUES (5,'HumansStore',2 )
INSERT #CompanyStore VALUES (6,'FoodStore',3 )
The final solution was pretty awesome I modified the usp_DrawTree to accept varchar vs ints because i had to make my query ids unique. I then just did a select/union all and built the parent child relationship.
select * into #TreeData from (
select ID='C' + cast(id as varchar(10)),
ParentID=null,
DataForBox=name + '(' + cast(id as varchar(10)) + ')',
ExtraInfo='',
SortColumn=name
from Company c
)
union all (
select ID='CG' + cast(id as varchar(10)),
ParentID=cg.CompanyID ,
DataForBox=name + '(' + cast(id as varchar(10)) + ')',
ExtraInfo='',
SortColumn=name
from CompanyGroup cg join Company c on c.ID=cg.CompanyID
)
//union all rest of hierarchy
)
Brad Schulz to the rescue in the form of usp_DrawTree.
you don't provide any table structure, so here is a sample of a recursive CTE processing a tree structure:
--go through a nested table supervisor - user table and display the chain
DECLARE #Contacts table (id varchar(6), first_name varchar(10), reports_to_id varchar(6))
INSERT #Contacts VALUES ('1','Jerome', NULL ) -- tree is as follows:
INSERT #Contacts VALUES ('2','Joe' ,'1') -- 1-Jerome
INSERT #Contacts VALUES ('3','Paul' ,'2') -- / \
INSERT #Contacts VALUES ('4','Jack' ,'3') -- 2-Joe 9-Bill
INSERT #Contacts VALUES ('5','Daniel','3') -- / \ \
INSERT #Contacts VALUES ('6','David' ,'2') -- 3-Paul 6-David 10-Sam
INSERT #Contacts VALUES ('7','Ian' ,'6') -- / \ / \
INSERT #Contacts VALUES ('8','Helen' ,'6') -- 4-Jack 5-Daniel 7-Ian 8-Helen
INSERT #Contacts VALUES ('9','Bill ' ,'1') --
INSERT #Contacts VALUES ('10','Sam' ,'9') --
DECLARE #Root_id char(4)
--get complete tree---------------------------------------------------
SET #Root_id=null
PRINT '#Root_id='+COALESCE(''''+#Root_id+'''','null')
;WITH StaffTree AS
(
SELECT
c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
FROM #Contacts c
LEFT OUTER JOIN #Contacts cc ON c.reports_to_id=cc.id
WHERE c.id=#Root_id OR (#Root_id IS NULL AND c.reports_to_id IS NULL)
UNION ALL
SELECT
s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
FROM StaffTree t
INNER JOIN #Contacts s ON t.id=s.reports_to_id
WHERE s.reports_to_id=#Root_id OR #Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree
--get all below 2---------------------------------------------------
SET #Root_id=2
PRINT '#Root_id='+COALESCE(''''+#Root_id+'''','null')
;WITH StaffTree AS
(
SELECT
c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
FROM #Contacts c
LEFT OUTER JOIN #Contacts cc ON c.reports_to_id=cc.id
WHERE c.id=#Root_id OR (#Root_id IS NULL AND c.reports_to_id IS NULL)
UNION ALL
SELECT
s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
FROM StaffTree t
INNER JOIN #Contacts s ON t.id=s.reports_to_id
WHERE s.reports_to_id=#Root_id OR #Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree
--get all below 6---------------------------------------------------
SET #Root_id=6
PRINT '#Root_id='+COALESCE(''''+#Root_id+'''','null')
;WITH StaffTree AS
(
SELECT
c.id, c.first_name, c.reports_to_id, c.reports_to_id as Manager_id, cc.first_name AS Manager_first_name, 1 AS LevelOf
FROM #Contacts c
LEFT OUTER JOIN #Contacts cc ON c.reports_to_id=cc.id
WHERE c.id=#Root_id OR (#Root_id IS NULL AND c.reports_to_id IS NULL)
UNION ALL
SELECT
s.id, s.first_name, s.reports_to_id, t.id, t.first_name, t.LevelOf+1
FROM StaffTree t
INNER JOIN #Contacts s ON t.id=s.reports_to_id
WHERE s.reports_to_id=#Root_id OR #Root_id IS NULL OR t.LevelOf>1
)
SELECT * FROM StaffTree
OUTPUT:
#Root_id=null
id first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
1 Jerome NULL NULL NULL 1
2 Joe 1 1 Jerome 2
9 Bill 1 1 Jerome 2
10 Sam 9 9 Bill 3
3 Paul 2 2 Joe 3
6 David 2 2 Joe 3
7 Ian 6 6 David 4
8 Helen 6 6 David 4
4 Jack 3 3 Paul 4
5 Daniel 3 3 Paul 4
(10 row(s) affected)
#Root_id='2 '
id first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
2 Joe 1 1 Jerome 1
3 Paul 2 2 Joe 2
6 David 2 2 Joe 2
7 Ian 6 6 David 3
8 Helen 6 6 David 3
4 Jack 3 3 Paul 3
5 Daniel 3 3 Paul 3
(7 row(s) affected)
#Root_id='6 '
id first_name reports_to_id Manager_id Manager_first_name LevelOf
------ ---------- ------------- ---------- ------------------ -----------
6 David 2 2 Joe 1
7 Ian 6 6 David 2
8 Helen 6 6 David 2
(3 row(s) affected)
EDIT based on OP's given tables and data:
try something like this:
SET NOCOUNT ON
DECLARE #Company table (id int, name varchar(40) )
INSERT #Company VALUES (1,'Living Things' )
INSERT #Company VALUES (2,'Boring Company' )
DECLARE #CompanyGroup table (id int, name varchar(40), CompanyID int)
INSERT #CompanyGroup VALUES (1,'Pets' ,1 )
INSERT #CompanyGroup VALUES (2,'Humans' ,1 )
INSERT #CompanyGroup VALUES (3,'Electronics' ,2 )
INSERT #CompanyGroup VALUES (4,'Food' ,2 )
DECLARE #CompanyStore table (id int, name varchar(40), CompanyGroupID int)
INSERT #CompanyStore VALUES (1,'PetsStoreA' ,1 )
INSERT #CompanyStore VALUES (2,'PetsStoreB' ,1 )
INSERT #CompanyStore VALUES (3,'PetsStoreC' ,1 )
INSERT #CompanyStore VALUES (4,'PetsStoreD' ,1)
INSERT #CompanyStore VALUES (5,'HumansStore' ,2 )
INSERT #CompanyStore VALUES (6,'FoodStore' ,3 )
--not provided by the OP, so I made it up
DECLARE #CompanyEmployees table (id int, name varchar(10), reports_to_id int, CompanyStoreID int)
INSERT #CompanyEmployees VALUES (1,'Jerome', NULL ,1) -- tree is as follows:
INSERT #CompanyEmployees VALUES (2,'Joe' ,1 ,1) -- PetsStoreA PetsStoreB PetStoreC FoodStore
INSERT #CompanyEmployees VALUES (3,'Paul' ,2 ,1) -- 1-Jerome 11-Alan 14-Ben 18-apple
INSERT #CompanyEmployees VALUES (4,'Jack' ,3 ,1) -- / \ / \ / / \
INSERT #CompanyEmployees VALUES (5,'Daniel',3 ,1) -- 2-Joe 9-Bill 12-Ally 13-Abby 15-Bill 19-pear 20-grape
INSERT #CompanyEmployees VALUES (6,'David' ,2 ,1) -- / \ \ / \ /
INSERT #CompanyEmployees VALUES (7,'Ian' ,6 ,1) -- 3-Paul 6-David 10-Sam 16-Bjorn 17-Benny 21-rasin
INSERT #CompanyEmployees VALUES (8,'Helen' ,6 ,1) -- / \ / \
INSERT #CompanyEmployees VALUES (9,'Bill ' ,1 ,1) -- 4-Jack 5-Daniel 7-Ian 8-Helen
INSERT #CompanyEmployees VALUES (10,'Sam' ,9 ,1) --
INSERT #CompanyEmployees VALUES (11,'Alan' ,NULL ,2) --to see all trees, scroll--->>
INSERT #CompanyEmployees VALUES (12,'Ally' ,11 ,2) --
INSERT #CompanyEmployees VALUES (13,'Abby' ,11 ,2) --
INSERT #CompanyEmployees VALUES (14,'Ben' ,NULL ,3) --
INSERT #CompanyEmployees VALUES (15,'Bill' ,14 ,3) --
INSERT #CompanyEmployees VALUES (16,'Bjorn',15 ,3) --
INSERT #CompanyEmployees VALUES (17,'Benny',15 ,3) --
INSERT #CompanyEmployees VALUES (18,'apple',NULL ,6) --
INSERT #CompanyEmployees VALUES (19,'pear' ,18 ,6) --
INSERT #CompanyEmployees VALUES (20,'grape',18 ,6) --
INSERT #CompanyEmployees VALUES (21,'rasin',21 ,6) --
SET NOCOUNT OFF
;WITH StaffTree AS
(
SELECT
c.id, c.name, c.reports_to_id, c.reports_to_id as Manager_id, cc.name AS Manager_name, 1 AS LevelOf, c.CompanyStoreID
FROM #CompanyEmployees c
LEFT OUTER JOIN #CompanyEmployees cc ON c.reports_to_id=cc.id
WHERE c.reports_to_id IS NULL
UNION ALL
SELECT
s.id, s.name, s.reports_to_id, t.id, t.name, t.LevelOf+1, s.CompanyStoreID
FROM StaffTree t
INNER JOIN #CompanyEmployees s ON t.id=s.reports_to_id
)
SELECT
c.id AS CompanyID, c.name AS CompanyName
,g.id AS CompanyGroupID, g.name AS CompanyName
,s.id AS CompanyStoreID, s.name AS CompanyStoreName
,t.id AS EmployeeID, t.name as EmployeeName, t.Manager_id, t.Manager_name, t.LevelOf
FROM #Company c
LEFT JOIN #CompanyGroup g ON c.id=g.CompanyID
LEFT JOIN #CompanyStore s ON g.id=s.CompanyGroupID
LEFT JOIN StaffTree t ON s.id=t.CompanyStoreID
ORDER BY c.name,g.name,s.name,s.ID,t.LevelOf,t.name
OUTPUT:
CompanyID CompanyName CompanyGroupID CompanyName CompanyStoreID CompanyStoreName EmployeeID EmployeeName Manager_id Manager_name LevelOf
--------- -------------- -------------- ----------- -------------- ---------------- ----------- ------------ ----------- ------------ -------
2 Boring Company 3 Electronics 6 FoodStore 18 apple NULL NULL 1
2 Boring Company 3 Electronics 6 FoodStore 20 grape 18 apple 2
2 Boring Company 3 Electronics 6 FoodStore 19 pear 18 apple 2
2 Boring Company 4 Food NULL NULL NULL NULL NULL NULL NULL
1 Living Things 2 Humans 5 HumansStore NULL NULL NULL NULL NULL
1 Living Things 1 Pets 1 PetsStoreA 1 Jerome NULL NULL 1
1 Living Things 1 Pets 1 PetsStoreA 9 Bill 1 Jerome 2
1 Living Things 1 Pets 1 PetsStoreA 2 Joe 1 Jerome 2
1 Living Things 1 Pets 1 PetsStoreA 6 David 2 Joe 3
1 Living Things 1 Pets 1 PetsStoreA 3 Paul 2 Joe 3
1 Living Things 1 Pets 1 PetsStoreA 10 Sam 9 Bill 3
1 Living Things 1 Pets 1 PetsStoreA 5 Daniel 3 Paul 4
1 Living Things 1 Pets 1 PetsStoreA 8 Helen 6 David 4
1 Living Things 1 Pets 1 PetsStoreA 7 Ian 6 David 4
1 Living Things 1 Pets 1 PetsStoreA 4 Jack 3 Paul 4
1 Living Things 1 Pets 2 PetsStoreB 11 Alan NULL NULL 1
1 Living Things 1 Pets 2 PetsStoreB 13 Abby 11 Alan 2
1 Living Things 1 Pets 2 PetsStoreB 12 Ally 11 Alan 2
1 Living Things 1 Pets 3 PetsStoreC 14 Ben NULL NULL 1
1 Living Things 1 Pets 3 PetsStoreC 15 Bill 14 Ben 2
1 Living Things 1 Pets 3 PetsStoreC 17 Benny 15 Bill 3
1 Living Things 1 Pets 3 PetsStoreC 16 Bjorn 15 Bill 3
1 Living Things 1 Pets 4 PetsStoreD NULL NULL NULL NULL NULL
(23 row(s) affected)
EDIT after OP's edit stating that We would like to see it in tree form.
The question is tagged sql-server-2008 and hierarchical-data, and the OP wants to do complex formatting for display f the data. However this type of processing and display is not the realm of TSQL and is a very clear example of where the application language should process and format flat data provided by a SQL query. I have provided such a query that could be used by an application to build a visual tree display. Also note that the simple tree example (no more than two children per parent) might not be very realistic and when many children exist for a single parent, the display will become difficult to construct and not pleasing to the eye.
You could use reporting services to display it back which you get with SQL 2008; if you are lucky it might be setup already -- if not its quite easy to do that. You could use the drill in features in reporting services to get allow your users to drill in and out of the data as needed very easily.
In terms of the query; does the tree grow or is it fixed? The SQL Query to get the data out from the database is quite simple though.
Select
CompanyName,
CompanyGroupName,
CompanyStoreName,
CompanyEmployeeForename,
CompanyEmployeeSurname
From tblCompanies com
left outer join tblCompanyGroups cg
on com.CompanyGroupID = cg.CompanyGroupID
Left outer Join tblCompanyStore cs
on com.CompanyID = cs.CompanyID
left outer join tblCompanyEmployees ce
on com.CompanyID = ce.CompanyName
I believe SQL Server 2008 offers a new data type to help with this scenario. Here is a link that I believe will help - http://msdn.microsoft.com/en-us/magazine/cc794278.aspx. I didn't see it in any comments, so hope this helps.