1

I have two tables - Master and Child. Child table contains hierarchal data for MainId stored in Master table.

Master.Name is Unique

Master.MainId = Child.ChildId

Child.ParentId = Child.ChildId

I have to retrieve all data from Child table for Master.RelDate and Master.Name. I thought it was a straight forward query but somehow not able to pull desired output. I'm ending up with just one Child table record no matter how I write query.

Is it to do with table structure or my query?

Note: None of the ParentIds and ChildIds are in sequence. That data comes from another system, I just put those values for simplicity.

IF OBJECT_ID('tempdb..#Master') IS NOT NULL BEGIN DROP TABLE #Master END
GO
IF OBJECT_ID('tempdb..#Child') IS NOT NULL BEGIN DROP TABLE #Child END
GO
CREATE TABLE #Master
(
    Id BIGINT IDENTITY(1,1),
    RelDate DATE NOT NULL,
    MainId BIGINT NOT NULL,
    Name VARCHAR(512) NOT NULL
)
GO
CREATE TABLE #Child
(
    Id BIGINT IDENTITY(1,1),
    RelDate DATE NOT NULL,
    ChildId BIGINT NOT NULL,
    ParentId BIGINT NULL,
    Label VARCHAR(20) NULL,
    Value VARCHAR(1024) NULL
)
GO

INSERT INTO #Master(RelDate,MainId,Name) VALUES ('2019-01-01',1,'Name1')
INSERT INTO #Master(RelDate,MainId,Name) VALUES ('2019-01-01',11,'Name11')
GO
INSERT INTO #Child(RelDate,ChildId,ParentId,Label,Value) VALUES
('2019-01-01',1,2,'Level10',NULL)
,('2019-01-01',2,3,'Level09',NULL)
,('2019-01-01',3,4,'Level08',NULL)
,('2019-01-01',4,5,'Level07',NULL)
,('2019-01-01',5,6,'Level06','This is level 6')
,('2019-01-01',6,7,'Level05',NULL)
,('2019-01-01',7,8,'Level04',NULL)
,('2019-01-01',8,9,'Level03','This is level 3')
,('2019-01-01',9,10,'Level02',NULL)
,('2019-01-01',10,11,'Level01',NULL) -- Always same
,('2019-01-01',11,NULL,'Root',NULL) -- Always same

INSERT INTO #Child(RelDate,ChildId,ParentId,Label,Value) VALUES
('2019-01-01',11,12,'Level10',NULL)
,('2019-01-01',12,13,'Level09',NULL)
,('2019-01-01',13,14,'Level08',NULL)
,('2019-01-01',14,15,'Level07',NULL)
,('2019-01-01',15,16,'Level06','This is level 6')
,('2019-01-01',16,17,'Level05',NULL)
,('2019-01-01',17,18,'Level04',NULL)
,('2019-01-01',18,19,'Level03','This is level 3')
,('2019-01-01',19,10,'Level02',NULL)
,('2019-01-01',10,11,'Level01',NULL) -- Always same
,('2019-01-01',11,NULL,'Root',NULL) -- Always same
GO

SELECT * FROM #Master
SELECT * FROM #Child

Desired output for RelDate = 2019-01-01 and Name = Name1

SELECT chld.*
FROM #Master mst (NOLOCK)
    INNER JOIN #Child chld (NOLOCK) ON (mst.MainId = chld.ChildId)
    LEFT JOIN #Child chld1 (NOLOCK) ON (chld.ParentId = chld.ChildId)
WHERE mst.RelDate = '2019-01-01' -- Input 1
AND mst.Name = 'Name1' -- Input 2

All the data from Child table

Id  RelDate ChildId ParentId    Label   Value
1   2019-01-01  1   2   Level10 NULL
2   2019-01-01  2   3   Level09 NULL
3   2019-01-01  3   4   Level08 NULL
4   2019-01-01  4   5   Level07 NULL
5   2019-01-01  5   6   Level06 This is level 6
6   2019-01-01  6   7   Level05 NULL
7   2019-01-01  7   8   Level04 NULL
8   2019-01-01  8   9   Level03 This is level 3
9   2019-01-01  9   10  Level02 NULL
10  2019-01-01  10  11  Level01 NULL
11  2019-01-01  11  NULL    Root    NULL

Thanks in advance

Tech Sawy
  • 91
  • 7
  • share your desired output – Zaynul Abadin Tuhin Sep 24 '19 at 10:12
  • Included output in the question – Tech Sawy Sep 24 '19 at 10:27
  • You need a recursive CTE for this, and also remove your loops in your data (10 to 19, 19 to 18... back to 10, then 10 to 19 again makes an infinite loop). – EzLo Sep 24 '19 at 11:46
  • @EzLo that's how the data is. Those Ids are from other system, no control over that. Do you have CTE example? – Tech Sawy Sep 24 '19 at 12:05
  • [This](https://stackoverflow.com/questions/42119057/sql-recursive-cte-finding-objects-linked-by-property/42139978#42139978) answer demonstrates a method for handling loops in data by keeping track of the rows already processed. – HABO Sep 24 '19 at 18:32

2 Answers2

0
select c.* from #Child c inner join #Master M
on M.MainId = C.ChildId

Id  RelDate ChildId ParentId    Label   Value
1   2019-01-01  1   2   Level10 NULL
11  2019-01-01  11  NULL    Root    NULL

If this isn't the desired output, please provide your desired output.

Fahmi
  • 37,315
  • 5
  • 22
  • 31
0

It seams that data in the tables is kinda non logical. Especially with the 'Name11'. I assume that with every new rows you will lose one id from Childid column .Now we lose 'lvl2' at row 19.
I tried to figure out some solution, now my position here.
It works for 'Name1', but result for 'Name11' a bit different.

SELECT   t2.* 
FROM #Master mst 
      join  #Child t1 ON mst.MainId = t1.ChildId
           join  #Child t2 ON t2.parentid >= t1.ChildId  

WHERE mst.RelDate = '2019-01-01' -- Input 1
AND mst.Name = 'Name1'           -- Input 2

order by t2.id 
offset 0 rows 
fetch first 10 rows only

Maybe it helps you a little. I will try to find a tricky solution.

Andriy
  • 123
  • 1
  • 9
  • thanks for your input. I think I should have mentioned that none on ParentId and ChildId are in sequence. That data comes from another system, I just put those values for simplicity. – Tech Sawy Sep 24 '19 at 13:19
  • Can't edit comments for some reason. ParentId and ChildId are NOT in sequence – Tech Sawy Sep 24 '19 at 13:43