Should I use Full Join in this multi-database SQL Server query - sql-server

I have a query supposedly with a output like this:
And here is my query:
select
table4.categoryNames, -- because only table4 has all the categories
table1.countResult, -- either (DATA) or null
table2.countResult,
table3.countResult,
table4.countResult,
table5.countResult,
table6.countResult,
table7.countResult
from
table1
full join
table2 on table1.categoryNames = table2.CategoryNames
full join
table3 on table2.categoryNames = table3.CategoryNames
full join
table4 on table3.categoryNames = table4.CategoryNames
full join
table5 on table4.categoryNames = table5.CategoryNames
full join
table6 on table5.categoryNames = table6.CategoryNames
full join
table7 on table6.categoryNames = table7.CategoryNames
and each countResult is a query itself counting IDs grouped by the field CategoryNames of table someTable in its respective database:
with table1 as
(
select
categroyName, count(ID) as countResult
from
database1.someTable
group by
categroyName),
-- table2 from database2.someTable
-- table3 from database3.someTable , and so on
I wish there is a category table, but there is none. The output is not correct, because it shows a 7th category with the name NULL.
I am new to SQL and I just want to know what is the best join I should use in this case.

I think union all and group by might be a better approach. Here is the basic idea:
select categoryName,
max(cr1), max(cr2), max(cr3), max(cr4), max(cr5), max(cr6), max(cr7)
from ((select categoryName, countResults as cr1, NULL as cr2, NULL as cr3,
NULL as cr4, NULL as cr5, NULL as cr6, NULL as cr7
from table1
) union all
(select categoryName, NULL as cr1, countResults as cr2, NULL as cr3,
NULL as cr4, NULL as cr5, NULL as cr6, NULL as cr7
from table2
) union all
. . .
) t
group by categoryName;
If you have all the categories in a table, then another approach is to use left join:
select c.categoryname, t1.countResult, t2.countResult, . . .
from categories c left join
table1 t1
on c.categoryname = t1.categoryname left join
table2 t2
on c.categoryname = t2.categoryname left join
. . . ;

Related

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

SQL Server Conditional JOIN two tables

I have 3 Tables:
TableA(IDRem, IDPed, IDOP)
TableB(IDOP, IDPed)
TableC(IDPed, InvoiceDate)
I need a select to JOIN the records of TableA and TableC, but there are two possible conditions:
IF IDPed on TableA IS NOT NULL, then join directly to TableC by IDPed
ID IDPed on TableA IS NULL, then join to TableB by IDOp, and then join TableB to TableC by IDPed
So far i try this:
SELECT
TableA.*
,(CASE WHEN TableC.InvoiceDate IS NULL
THEN TableC2.InvoiceDate
ELSE TableC.InvoiceDate
END) AS InvoiceDate
FROM
TableA
LEFT JOIN TableC on TableA.IDPed = TableC.IDPed
LEFT JOIN TableB on TableB.IDOp = TableA.IDOp
INNER JOIN TableC as TableC2 on TableC2.IDPed = TableB.IDPed
The problem with this is that every field o tableA I want to include in the select I need to do a case...when to determine if the origin is tableA or TableA2.
Is there a better way of doing this? Thanks!
For complex joins you are better served in TSQL using cross apply:
When should I use Cross Apply over Inner Join?
select IDRem, IDPed, IDOP from TableA a
cross apply(
select IDOP, IDPed from TableB binner
where a.IDop = binner.IDop
) b
cross apply(
select IDPed, InvoiceDate cinner
where b.IDPed = cinner.IDPed
) c
where ...
Strictly psuedo-code but should give you a start.
You could try doing both JOINs and use UNION ALL
Edit: As pointed out in the comment by Vladimir Baranov, there's no need to check if a.IdPed IS NULL on the first SELECT since if it is, the JOIN would return no rows.
SELECT
a.*,
c.InvoiceDate
FROM TableA a
INNER JOIN TableC c ON c.IdPed = a.IdPed
UNION ALL
SELECT
a.*,
c.InvoiceDate
FROM TableA a
INNER JOIN TableB b ON b.IdOp = a.IdOP
INNER JOIN TableC c ON c.IdPed = b.IdPed
WHERE a.IdPed IS NULL

Oracle join query in sqlserver

Here is the sample oracle query i need to be changed to SQLSERVER 2008.Basically it gets the description from table2 for the scode and if there is no or null description using 'case' it is made to 'unknown'. How to do.
select a.scode,b.description,a.amt,a.purid
from
(select scode,ISNULL(SUM(AMOUNT),0) AS AMT,count(pur_ID)
from table1
where scode is not null
group by scode)A, table2 B WHERE A.SOURCE_CODE =+B.SOURCE
Try this (Please note I am joining with =):
Select A.Scode, A.Amt, A.Counts, IsNull(B.Description, 'Unknown') Descripton
From (
select Scode, SOURCE_CODE, Isnull(sum(amount),0) as Amt, count(pur_ID) Counts
from table1
where scode is not null
group by scode, SOURCE_CODE
) A left join table2 B on A.SOURCE_CODE = B.SOURCE
Edit as per comments:
Select A.Scode, Isnull(sum(A.amount),0) as Amt,
count(A.pur_ID) Counts, IsNull(Max(B.description), 'Unknown') description
From Table1 A Left Join Table2 B
On A.SOURCE_CODE = B.SOURCE
Where A.Scode is not null
Group by A.Scode

Using where condition in sql query

I have an sql query like this
Select col1, (select abc from table2 where def=1) as col2
From Table1 inner join table3 on Table1.id = table3.id
Where col2 = 4
The problem is that the where condition doesn't work. I get an error saying
Invalid column name 'col2'
Kindly help me fix this sql query.
Thanks in advance
You can define it in a CROSS APPLY and then reference in the SELECT and WHERE
SELECT col1,
col2
FROM Table1
INNER JOIN table3
ON Table1.id = table3.id
CROSS APPLY (SELECT abc
FROM table2
WHERE def = 1) C(col2)
WHERE col2 = 4
Using a CTE (Common Table Expression):
WITH SubQuery AS (Col2) {
SELECT
ABC
FROM
table2
WHERE
def = 1
}
SELECT
T.Col1,
S.Col2
FROM
SubQuery S,
Table1 T
INNER JOIN table3 t3
ON T.id = t3.id
WHERE
S.Col2 = 4
Although I must say I agree with the first comment - this makes no sense since your subquery is not correlated (joined) to the rest of your query...

Use of if exists( ) in select statement

I need to fetch a column from table2, if row exists, if not return it as null.
If i use ,case when it fetches only matched rows between table1 and table2.
If i use left outer join it fetches all the rows from table1 even though
condition table1.code='A'
So i need ,some thing like this.
select table1.id,
if(row exist in table2 for query(table2.relation_type_id=55 and table1.id=table2.related_id)
then
return table2.parent_id
else
null
as parent_id,
table1.description,
from table1,table2 where table1.code='A'
SELECT table1.id, table2.parent_id as parent_id
FROM table1
LEFT OUTER JOIN table2 ON (table1.id = table2.related_id)
WHERE table1.code = 'A';
EDIT based on comment :
SELECT table1.id, sub.parent_id as parent_id
FROM table1
LEFT OUTER JOIN (select parent_id,related_id from table2 where relation_type_id =55) sub ON (table1.id = sub.related_id)
WHERE table1.code = 'A';
Have you tried a sub-query?
select table1.id,
(select table2.parent_id from table2 where table2.relation_type_id=55 and table2.related_id=table1.id) parent_id,
table1.description,
from table1 where table1.code='A'

Resources