how to Join five Tables with one another dependency in SQL - sql-server

I want to join five tables in SQL server. The sequence as given below. Logic should be
Table1 >>>>Key : ID >>>> Table_A & Table_B (If Table1.Status = ABC then Table_A else Table_B ) >>> Key : NUMBER >>> Table2 >>> Key : Number + Item_No >>> Table3
Please help if below code could work.
SELECT * FROM
TABLE1
LEFT JOIN (CASE WHEN status = 'ABC' THEN Table_A ELSE Table_B END ) X ON (Table1.ID = X.ID)
LEFT JOIN Table2 ON (X.NUMBER = Table2.NUMBER)
LEFT JOIN Table3 ON (Table3.CONCAT(NUMBER + Item_No) = Table2.CONCAT(NUMBER + Item_No))

SELECT Q.*, T2.ItemNo, T2.Product, T3.Connection
FROM (
SELECT T1.ID, CASE WHEN T1.Status = 'ABC'
THEN TA.Number
ELSE TB.Number
END as Number
FROM Table1 T1
LEFT JOIN TableA TA
ON T1.ID = TA.ID
LEFT JOIN TableB TB
ON T1.ID = TB.ID
) as Q
JOIN Table2 T2
ON Q.Number = T2.Number
JOIN Table3 T3
ON T2.ItemNo = T3.ItemNo

Related

Different Filters for Different Columns

I am relatively new to SQL and I have the following question. I have the following code:
Select * from table1
LEFT JOIN table2 ON table1.name = table2.name and table1.id = table2.id
LEFT JOIN (SELECT id FROM table2 GROUP BY id) newtable ON table1.id = newtable.id
As both left joins uses data from the same table, is it possible to combine the two joins into one? How would the filters work in this case?
If your goal just to join table2 based on distinct values, then you can use WHERE and GROUP BY:
Select
*
from table1 t1
LEFT JOIN table2 t2
ON t1.name = t2.name and t1.id = t2.id
WHERE t1 id in (SELECT s2.id FROM table2 s2 GROUP BY s2.id)

SQL Server : left join - check for right table column value is null

I have a query as follows:
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo,
CASE WHEN tbl3.Comments IS NOT NULL THEN 1 ELSE 0 END AS 'Required'
from
table1 tbl1
inner join
table2 tbl2 on tbl2.Id = tbl1.Id
left join -- This left join table gives me 5 records for one instance
(select
R.Id, C.Comments
from
tblC C
inner join
tblR R on R.Id = C.id) tbl3 on tbl3.Id = tbl2.Id
I want to write a CASE statement on the rows my left join is giving to check for null value as above and my final select query always return only 1 row. Is there a way to check if all five Comments Column values from my left join be checked for NULLs in the above query?
I would take a shortcut an use a COUNT() OVER PARTITION
CASE WHEN COUNT(*) OVER (PARTITION BY tbl3.Id) =0 THEN 0 ELSE 1 END AS 'Required'
You would have to DISTINCT your output above. Another option would be to GROUP BY and filter in the HAVING clause.
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo
From table1 tbl1
inner join table2 tbl2 on tbl2.Id = tbl1.Id
left join (-- This left join table gives me 5 records for one instance
SELECT R.Id,
C.Comments
FROM tblC C
INNER JOIN tblR R on R.Id = C.id
) tbl3 on tbl3.Id = tbl2.Id
GROUP BY
Id, Name, Address, relNo
HAVING
COUNT(*) = 5
Is this what you're looking for?
(CASE WHEN (select count(tbl3.id) FROM tbl3 WHERE tbl3.Comments IS NULL) then 1 else 0 end) as 'RequiredVal'
select --this select should always give me 1 record
tbl1.Id, tbl1.Name, tbl1.Address, tbl2.relNo,
CASE WHEN tbl3.Comments IS NOT NULL THEN 1 ELSE 0 END AS 'Required'
, (CASE WHEN (select count(tbl3.id) FROM tbl3 WHERE tbl3.Comments IS NULL) then 1 else 0 end) as 'RequiredVal'
From table1 tbl1
inner join table2 tbl2 on tbl2.Id = tbl1.Id
left join (-- This left join table gives me 5 records for one instance
SELECT R.Id,
C.Comments
FROM tblC C
INNER JOIN tblR R on R.Id = C.id
) tbl3 on tbl3.Id = tbl2.Id

MSSQL Query framing

I have 3 tables like master and 2 child tables . I am using join condition but did not get as expected client needs.
Query:
select * from(
select a.id as mid,b.id,b.val from ##mastertable a right join ##table1 b
on a.id=b.id ) as c inner join ##table2 d on c.mid=d.id
Kindly provide any other way to get proper result.
Try:
Select a.id, b.id, b.val
From (mastertable a
Right Join table1 b
On a.id = b.id)
Inner Join table2 d
On a.id = d.id;
This should work :
select * from (
(select master.id from master_table) master
LEFT OUTER JOIN
(select table1.id, table1.value from table_1) table1
ON
master.id = table1.id
FULL OUTER JOIN
(select table2.id, table2.value from table_2) table2
ON
table1.id = table2.id
AND
table1.val = table2.val
)
;
Try below: https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=2b58625961c444997829abb45d40417b
select * from master m inner join
(select table2.id as id1, table2.value as val1, table1.value as val2, table1.id as id2
from table2 left join table1
on table1.id=table2.id and table1.value=table2.value)x on m.id=x.id1
This will be same as you expected
select
m.id, t1.id, t1.value, t2.id, t2.value
from
m
left join
t1
on
m.id = t1.id
left join
t2
on
t1.id = t2.id and t1.value = t2.value
order by m.id, t1.value
here M is your master table, T1 is table1 and t2 is table2

SQL Query: customer name including activity count

There's probably a very simple solution to this that I'm not seeing right now.
I need a script for an SQL report. I can get all customer names in a simple SELECT:
SELECT
t5.[Name] AS CustomerName
FROM
[T5] t5
WHERE
t5.Type IN (1, 2)
ORDER BY
t5.[Name]
This gives me an ordered list for the dropdown menu, to select the customer name. The result set looks like this:
CustomerName
------------
Customer 1 Name
Customer 2 Name
Customer 3 Name
...
But I don't just need the name, I need the number of related activities to that customer name inside the name string as well. For example, with 38 activities for that customer it should look like : "(38) Customer Name here"
The statement giving me the correct count for one particular customer (in this example, "Customer 5 Name") looks something like this, it needs a couple of joins to get there:
SELECT
COUNT(*)
FROM
[T1] t1
INNER JOIN
[T2] t2 ON t2.[ID] = t1.[Activity]
INNER JOIN
[T3] t3 ON t3.[ID] = t2.[Username]
INNER JOIN
[T4] t4 ON t4.[ID] = t3.[ID]
INNER JOIN
[T5] t5 ON t5.[ID] = t4.[X]
WHERE
t5.[Name] = 'Customer 5 Name'
Now obviously I need to combine these somehow, to get the following result set:
CustomerName
-------------------
(a) Customer 1 Name
(b) Customer 2 Name
(c) Customer 3 Name
(d) Customer 4 Name
(e) Customer 5 Name
(f) Customer 6 Name
...
(a-f being the respective activity count for that customer)
Thanks for help!
WITH pre AS
(
SELECT t5.[Name] AS CustomerName, COUNT(*) AS ActivityCount
FROM [T1] t1
INNER JOIN [T2] t2 ON t2.[ID] = t1.[Activity]
INNER JOIN [T3] t3 ON t3.[ID] = t2.[Username]
INNER JOIN [T4] t4 ON t4.[ID] = t3.[ID]
INNER JOIN [T5] t5 ON t5.[ID] = t4.[X]
WHERE t5.Type IN (1, 2) AND t5.[Name] = 'Customer 5 Name'
GROUP BY t5.Name
)
SELECT '(' + ActivityCount + ') ' + CustomerName
FROM pre
You should use group by
SELECT
t5.[Name], COUNT(*)
FROM
[T1] t1
INNER JOIN
[T2] t2 ON t2.[ID] = t1.[Activity]
INNER JOIN
[T3] t3 ON t3.[ID] = t2.[Username]
INNER JOIN
[T4] t4 ON t4.[ID] = t3.[ID]
INNER JOIN
[T5] t5 ON t5.[ID] = t4.[X]
group by t5.[Name]
I Think this will give you the number with the customer name as per your requirement.
SELECT
'(' + CAST(COUNT(*) AS nvarchar(4) ) + ') ' + t5.[Name] as [CustomerName]
FROM
[T1] t1
INNER JOIN
[T2] t2 ON t2.[ID] = t1.[Activity]
INNER JOIN
[T3] t3 ON t3.[ID] = t2.[Username]
INNER JOIN
[T4] t4 ON t4.[ID] = t3.[ID]
INNER JOIN
[T5] t5 ON t5.[ID] = t4.[X]
group by t5.[Name]

Change Sql "Not In" To "Left Outer Join"

I don't want to use "not in" this sql query. How can I do it? thanks
SELECT
T2.Sno,
T2.Name,
T1.description,
T2.UserCode
FROM
Table1 AS T1 (nolock)
INNER JOIN T2 (nolock)
ON T1.UserCode = T2.UserCode
WHERE
g.xid= #p_xid
and T2.Sno not in (select Gid from T3 (nolock))
Assuming there is no row in T2 where Sno is null and in T3 where Gid is null:
SELECT
T2.Sno,
T2.Name,
T1.description,
T2.UserCode
FROM
Table1 AS T1 WITH (nolock)
INNER JOIN T2 WITH (nolock)
LEFT JOIN T3 WITH (NOLOCK)
ON T2.Sno = T3.Gid
ON T1.UserCode = T2.UserCode
WHERE
g.xid= #p_xid
and T3.Gid IS NULL
If you have multiple T3 rows per T2.Sno = T3.Gid, you'll need DISTINCT in a JOIN.
Without DISTINCT, it's a different query
With DISTINCT, it's an extra step.
I'd use NOT EXISTS which avoids this.
SELECT
T2.Sno,
T2.Name,
T1.description,
T2.UserCode
FROM
Table1 AS T1 (nolock)
INNER JOIN T2 (nolock)
ON T1.UserCode = T2.UserCode
WHERE
g.xid= #p_xid
and not exists (select * from T3 (nolock) where T3.Gid = T2.Sno)

Resources