Show missing data and list with existing data - sql

I have 2 tables
a table of PARENT ACCOUNTS (holds PARENT ID and CHILD ID)
a table of CHILD ACCOUNTS (Holds CHILD ID and ATTRIBUTE)
1 PARENT can have many CHILDREN
Each Child has one or more attributes, and each child must have the same as the other in the parent group
so if Parent 1 has Child1, Child2, Child3
Child1, Child2, Child3 MUST have the same attribute - say they are BLUE
If Child3 is missing this attribute (doesn't exist) then I need to show All the Child accounts and highlight which one is the missing one.
select Child, Parent,Attribute
from
[dbo].[AttributeTable] as AttReq
LEFT OUTER JOIN
[dbo].[ChildDetails] ChildDetails
ON AttReq.Child = ChildDetails.Child
where Parent = 'Parent1'
CHILD ACOUNT
PARENT ACCOUNT
ATTRIBUTE
Child1
Parent1
Attribute 1
Child1
Parent1
Attribute 2
Child1
Parent1
Attribute 3
Child2
Parent1
Attribute 1
Child2
Parent1
Attribute 4
Child2
Parent1
Attribute 2
Child2
Parent1
Attribute 3
Child3
Parent1
Attribute 1
Child3
Parent1
Attribute 2
Child3
Parent1
Attribute 3
So this one, only Child 2 has attribute 4.
I want to list all the Child accounts that are missing 4 - and which one HAS 4. I don't need to show which ones they all have.
CHILD ACOUNT
PARENT ACCOUNT
ATTRIBUTE
Child1
Parent1
Missing Attribute 4
Child2
Parent1
Missing Attribute 4
Child3
Parent1
Has Attribute 4

If you are evaluating the instances of an attribute across several attributes, you need a sub-query to evaluate at a higher level of analysis.
I would probably do this with a case statement that sums the instances of the attribute you are looking for across each child.
To take your query as the sub-query:
SELECT SUM(CASE WHEN ATTRIBUTE = 'Attribute 4' THEN 1 ELSE 0 END) [Attribute Count]
,Child
,Parent
FROM(
SELECT Child
,Parent
,Attribute
FROM [dbo].[AttributeTable] as AttReq
LEFT OUTER JOIN [dbo].[ChildDetails] ChildDetails
ON AttReq.Child = ChildDetails.Child
WHERE Parent = 'Parent1'
) Subquery
GROUP BY Child
,Parent
A child with [Attribute Count] more than 0 have the attribute. Those with 0 do not have the attribute.

Related

Multi-level hierarchy data display in SQL Server Management Studio

I want to fetch a multi-level hierarchy in a sequential manner. I have a table BOMHierarchy in which I have this sample data:
Parent
Child
Parent1
Child1
Parent1
child2
Child1
Child3
Child1
Child4
Child3
Child5
Child3
Child6
I want to show the above data like below in proper hierarchical manner:
Parent
Child
Parent1
Child1
Child1
Child3
Child3
Child5
Child3
Child6
Child1
Child4
Parent1
Child2
I am stuck at fetching this sequential data according to the hierarchy. Can anyone please provide a solution?
I have tried using a CTE and while loop but I'm not getting the required result.
Looks like a classic problem of how to recursively scan a tree. In SQL is simple, what you just need is to create the right ORDER BY.
Try something like this
DECLARE #BOM table (Parent varchar(20), Child varchar(20))
INSERT INTO #BOM(Parent, Child)
VALUES ('Parent1', 'Child1'),
('Parent1', 'Child2'),
('Child1', 'Child3'), ('Child1', 'Child4'),
('Child3', 'Child5'), ('Child3', 'Child6')
-- find all possible combinations recursively
;WITH cte AS
(
SELECT
Parent, Child,
CONVERT(VARCHAR(MAX),Parent + '|' + Child) Chain
FROM
#BOM root
WHERE
NOT EXISTS (SELECT 1
FROM #BOM NotRoot
WHERE root.Parent = NotRoot.Child)
UNION ALL
SELECT
BOM.Parent, BOM.Child, cte.Chain + '|' + CONVERT(VARCHAR(MAX), BOM.Child) Chain
FROM
cte
INNER JOIN
#BOM BOM ON cte.Child = BOM.Parent
)
SELECT
Parent, Child
FROM
cte
ORDER BY
Chain

Get root element and all descendants MS SQL

I should get root element with all descendants from that structure:
rootA
rootB
child1
rootC
child2
chold3
rootD
child4
RESULT:
Root| Child
rootA child1
rootA child2
rootA child3
rootD child4
I understand, that firstly I should get root elements without parents:
SELECT DISTINCT
rootId,
childId
FROM
root
WHERE rootId IS NULL
But I dont know the next step.
Do you have some variants?
Thanks!
This is done with a Common Table Expression (CTE):
;WITH cte_hierarchy AS (
-- get all roots
SELECT DISTINCT
rootId, childId
FROM
root
WHERE rootId IS NULL
UNION ALL
-- this is the recursive part
-- get all children for all roots, including children of children, etc.
SELECT
child.rootId, child.childId
FROM root child
JOIN cte_hierarchy parent ON parent.childid=child.rootid
)
SELECT * FROM cte_hierarchy;

How to query items that have full match of its children in Child table

I have 2 tables: ParentChild and Child.
ParentChild table has 2 columns PID and CID, where 1 PID can map to multiple CIDs. Child table contains distinct CIDs. The thing is CIDs in Child table doesn't necessarily cover all CIDs in ParentChild table.
Now I want to find all PIDs that each PID has all its CIDs in Child table. Examples:
P1 has 3 CIDs, if all are in Child table, P1 is selected;
P2 has 2 CIDs, if not all are in Child table, P2 is not selected.
How do I write query in a clear and performant way?
One method uses aggregation:
select pc.pid
from parentchild pc left join
child c
on pc.cid = c.cid
group by pc.pid
having count(*) = count(c.cid);
The last condition checks that all children match.

SQL parent child recursive query - Includes Relatives relatives

I have the following Table with two columns.
Parent Child
A C
A D
B A
B E
C H
J C
F G
G I
So I need to pass in a Parent of A and I am supposed to get the following back- All of a's Parent's and children but Also all of the Parents and Children to those associated to A (either parent or children) I need all their parents and children and so on.
SO in the example of A being passed to the proc I would get the following
A C
A D
B A
B E
C H
J C
If F was Passed I would just get
F G
G I
select * from test
where parent in (
select parent from test
where parent = 'F' or child = 'F'
union
select child from test
where child = 'F' or parent = 'F')
or child in (
select parent from test
where parent = 'F' or child = 'F'
union
select child from test
where child = 'F' or parent = 'F');
Try this, it is similar to the link given in the comments but accounts for both parent and child recursion. Hopefully it will work for you.
WITH relationships AS (
SELECT *
FROM Table
WHERE Child = 'A'
UNION ALL
SELECT p.*
FROM Table p
JOIN relationships pa on pa.Child = p.Parent
UNION ALL
SELECT c.*
FROM Table c
JOIN relationships ch on ch.Parent = c.Child
)
select *
from name_tree;

Parent - child sql query with in a single table

I've a table:
Id | Name | ParentID
I want to select records whose parentid not equal to zero, with parent record(parent record have parentid = 0, but some parent record don't have child record I want to skip them )
Try this:
SELECT child.Id,
child.Name,
child.ParentId,
parent.Name as ParentName
FROM your_table child
JOIN your_table parent ON child.ParentId = parent.id;
Check this one:
select * from child c,parent p where c.ID=P.ParentID and c.ParentID !=0