Having trouble self joining a table with NULL values - sql

I have a single table that has the columns: personID, name, parentID1 and parentID2
Essentially I am looking to use this table to find a childs parent(s)
Not every child has both parents, so these values are NULL in the table. I have tried using self joins but it just is not working out for me.
TABLE
Here is what the table should look like:

Need to use LEFT joins so each row is returned even if the there is no match in the right table
List Parents for Each Person Even if 1 Parent is NULL
SELECT A.[name] AS Child
,B.[name] AS Parent1
,C.[name] AS Parent2
FROM YourTable AS A
LEFT JOIN YourTable AS B
ON A.ParentID1 = B.PersonID
LEFT JOIN YourTable AS C
ON A.ParentID2 = C.PersonID
WHERE A.ParentID1 IS NOT NULL
OR A.ParentID2 IS NOT NULL

Related

Join SQL output of a N-M relationship table [duplicate]

I want to join a table which has multiple rows and need to merge one of the column from all the rows into single column.
select a.parent_id,a.parent_name,concat(b.child_name) from parent a
join children b on (a.parent_id=b.parent_id);
This should return all the parent rows and each parent row should have all its children's.
i am thinking to group with parent_id but getting multiple records (one record per child). What logic i can implement here apart from grouping to get all child's for a parent in single row.
SELECT a.parent_id, a.parent_name, STRING_AGG(b.child_name, ',') as Children
FROM
Parent a
INNER JOIN children b
ON a.Id = b.ParentId
GROUP BY
a.parent_id
,a.parent_name

How to create view with select two relation table one to one, and fill all null value with parent value - postgreSQL

I have 2 tables, structured like this:
table A table B
- id - id
- name - name
- parent
- fk_b
so in table A there are parent and fk_b. for fk_b it can be null.
so if in table A (child) the fk_b is null will refer to table A (parent), for example on of the row in the table A (parent) has fk_b.
Note:
This parent contains the id of table A
my question is, how can we select table A join table B. But every table A with null fk_b will retrieve fk_b from its parent?
Thank you
You can self-join the table to retrieve the parent row, and implement conditional logic in the on clause of the join on tableb, like so:
select a.*, b.name
from tablea a
left join tablea p on p.id = a.parent
left join tableb b on b.id = coalesce(a.fk_b, p.fk_b)

SQL - How to query for same table, same column, different data?

I am trying to create a short hierarchy query in SQL.
Tables & Columns used (Schema)
In table table_A, I have employee information in columns: Name, ID (HR-type data).
In table table_B, I have relationship data in columns RelType, ChildID, ParentID.
Table_B's columnsChildID and ParentID are populated with table_A's ID data.
Example
If my table_A, ID is 1 and my boss's ID is 2, then in table_B, our relationship would be expressed by showing the ChildID as 1 and the ParentID as 2.
How do I write the query to pull in the Child HR data and the Parent HR data on the same row?
I can pull in all the Child HR data I need with below query, but cannot figure out how to join or alias in a way that will pull in table_A's column ID for two different values on the same row.
SELECT
table_a.name
table_a.id
table_b.reltype
FROM table_a
LEFT JOIN table_b ON table_a.id=table_b.childid
This obviously does not include any data for the Parent info. For every ID in table_A, if that ID exists in table_B, it will be in both Child and Parent ID columns. I want to capture all the "children" and include their "parent" (there will only be one for this purpose) on the same row.
EDIT: Below answer worked, needed two joins with aliases. Thx.
You seem to be looking for two joins on table_a, like so:
select
b.reltype
b.childid,
ac.name childname,
b.parentid,
ap.name parentname
from table_b b
inner join table_a ac on ac.id = b.childid
inner join table_a ap on ap.id = b.parentid

Select records whose id does not appear in multiple tables

I have 3 tables. Two tables (par1, par1) both refer (child_id) to an id in the 3rd table (child).
I like to find orphans in the 3rd table, i.e. records that are not referenced by either of the other two tables.
If I had only once referencing table, I could write:
SELECT * FROM child WHERE id NOT IN (SELECT child_id FROM par1)
But how do I solve this for two referencing tables?
I'm using sqlite.
SELECT *
FROM child
WHERE id NOT IN (SELECT child_id FROM par1) AND
id NOT IN (SELECT child_id FROM par2)
An alternative is to use LEFT OUTER JOIN:
SELECT child.*
FROM child LEFT OUTER JOIN par1 ON (child.id = par1.child_id)
LEFT OUTER JOIN par2 ON (child.id = par2.child_id)
WHERE par1.child_id IS NULL AND par2.child_id IS NULL
Executing subqueries may or may not find the desired optimization paths in the SQLite index decision engine.

How do I use a column value in a substrings where clause

03-30 13:17]
I'm trying to use a t-sql against SQL-Server 2005 with asp 3.0. What I want to do is first select all rows that match a certain condition and then I want to know how how many children are connected to that row based on it's ChildID.
This can of course be done by just doing two queries against the db one to get the matching rows for the Parent and one for each row that was found to know how many children have that as Parent.
I have two tables, table1 contains parents and children and table2 contains the information and the id here is ofcourse the id that is saved in parent and children in table1.
Now I want to first find all the children to a certain parent, and in the same sql-statement I want to know how many children is connected to each child.
So Parent 807 has two children, 808 and 809. 808 has 5 children and 809 has 72 children, how can I with one statement get both the information of children 808 and 809 and the numer of children connected to each of them.
My SQL looks like this (gets the children to parent 807)
SELECT Parent, Child, ID, FieldX, FieldY
FROM Tabel1 INNER JOIN Tabel2 ON Parent = ID
WHERE (Parent = 807)
The statement I use to get the numer of children connected to f.ex. 808 is as follows.
SELECT COUNT(*) AS AntalPoster
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = 808)
What I would like to do is the following, but I would like to substitute the value 808 with the value each record gives me for the child aka SearchID.
SELECT Parent, Child AS SearchID, ID, FieldX, FieldY,
(SELECT COUNT(*) AS [Antal sidor]
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = 808)) AS AntalPoster
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = 807)
The problem I get is that "Invalid column name 'SearchID'", what I can understand is that I can't get the value that I find in SerachID to be used as a value in the next SQL-statements where clause.
Is this possible, and if so how?
Thanks in advance.
So, I understand, basically Table1 contains hierarchy information, and Table2 details.
Assuming that, here's my approach:
SELECT
h.Parent,
h.ChCount,
d.* /* you may want to expand it to a specific Table2 column list */
FROM (
/* first, get the children and their child counts */
SELECT
p.Parent,
p.Child,
COUNT(*) AS ChCount
FROM Table1 p
INNER JOIN Table1 c ON p.Child = c.Parent
GROUP BY p.Parent, p.Child
WHERE p.Parent = 807
) h
/* next, get the children's details */
INNER JOIN Table2 d ON h.Child = d.ID
Now I want to first find all the children to a certain parent, and in the same sql-statement I want to know how many children is connected to each child.
This is a way to do that.
declare #Table1 table (Table1ID int, ParentID int)
-- Root
insert into #Table1 values(807, null)
-- Children to 807
insert into #Table1 values(808, 807)
insert into #Table1 values(809, 807)
-- Children to 808
insert into #Table1 values(810, 808)
-- Children to 809
insert into #Table1 values(811, 809)
insert into #Table1 values(812, 809)
select
T1.*,
(select count(*)
from #Table1 as T2
where T1.Table1ID = T2.ParentID) as ChildCount
from #Table1 as T1
where T1.ParentID = 807
Result
Table1ID ParentID ChildCount
----------- ----------- -----------
808 807 1
809 807 2
Replace
WHERE (Parent = SearchID))
by
WHERE (Parent = ParentID))
But you're better of using
SELECT Parent, Child, ID, FieldX, FieldY, COUNT(*) AS AntalPoster
FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
WHERE (Parent = [ParentID])
GROUP
BY Parent, Child, ID, FieldX, FieldY;
If you define a "alias" for a column you can't use this name inside the query earlier than within a group by or order by clause.
As is your example SearchID is just a name for column Child you should use WHERE (PARENT = Child)
You're kinda close.
SELECT Parent_ID, COUNT(*) AS AntalPoster FROM Tabel1 INNER JOIN Tabel2 ON Child = ID
Group by Parent_ID
Now I don' quite understand from reading your question what the 'ID' field is called...but the results of this query should give the Parent_ID along with the count of the number of child records (If I've read your setup corectly). Join to that subquerty to get the count.
SELECT Parent, Child.AntalPoster, ID, FieldX, FieldY
FROM Tabel1 INNER JOIN Tabel2 ON Parent = ID
inner join (SELECT Parent_ID, COUNT(*) AS AntalPoster FROM Tabel1 INNER JOIN Tabel2 ON Child = ID Group by Parent_ID) child on child.id = t1.ID
WHERE (Parent = 807)
Whats really confusing me in your example...if I'm still off with what you're going for...quickly giving us the schema would help. Is the table setup so it has Parent, Child, ID? If so, how does the work? I'd expect Parent_ID, Child_ID...bit confused on the third "ID" column, what does it hold thats unique from the parent,child columns that already exist?.
In any case, the logic is setup a subquery so it reads Key , Count(1). Then join to that subquery on the Key to obtain the count value the subquery returns.