SQL Server : Select statement with select case nested - sql-server

I have two tables
Table 1, columns: A, B, C
Table 2, columns: A, D, E
I want to select all from table 1 with an additional field added.
If the contents of string column table_1.A exists in table_2.A, then TRUE, if not then FALSE.
I'd love to tell you what I've tried, but nothing is coming close. I can do this with a SELECT CASE statement, but I can't figure out how to select all at the same time.
Thanks

Try using CASE
SELECT
table1.A,
table1.B,
table1.C,
CASE WHEN table2.A IS NULL THEN 'FALSE' ELSE 'TRUE' END
FROM
table1
LEFT OUTER JOIN
table2
ON table1.A = table2.A

SELECT T1.*, IIF(T2.D IS NULL, 'FALSE', 'TRUE')
FROM Table1 T1
LEFT JOIN Table2 T2 ON T2.A LIKE '%' + T1.A + '%'

You need a left outer join and them compare both tables using the case when columnab is not null then true else false

This would give you only one row per record in Table1.
SELECT Table1.*,
ISNULL([Found],'False') [Found]
FROM Table1
OUTER APPLY (
SELECT TOP 1
'True' AS [Found]
FROM Table2
WHERE Table2.A LIKE '%' + Table1.A + '%'
)

Related

Count of rows from a joined table SQL Server

Is it possible to make a count of rows (I am using a view) with a resultset of a subquery?
Assuming I have
Table1
t1id
Table2
id, t1id_Parent, t1id_Child
Table3
t1id
I query for
select
t1.t1id as id,
stuff((select ', ' + CAST(CASE WHEN t2.t1id_Child is not null THEN t2.t1id_Child ELSE '0' END AS varchar) from Table1 t where t.t1id_Parent = t1.t1id for xml path('')),1,2,'') as ids
FROM
Table1 as t1
LEFT OUTER JOIN
Table1 AS t2 ON t1.t1id = t2.t1id_Parent
So I have the needed ids combined into a string that looks like this '1,2,5,9' in the column named "ids" that is working correctly however what I need to do now is have this query
select
t1.t1id as id,
stuff((select ', ' + CAST(CASE WHEN t2.t1id_Child is not null THEN t2.t1id_Child ELSE '0' END AS varchar) from Table1 t where t.t1id_Parent = t1.t1id for xml path('')),1,2,'') as ids
FROM
Table1 as t1
LEFT OUTER JOIN
Table2 AS t2 ON t2.t1id_Parent = t1.t1id
LEFT OUTER JOIN
(select count(t1id) as rows_count, t1id
from Table3
group by t1id) as docs ON docs.t1id in (ids)
to retrieve the row count from the 3rd table using the temporary column however I am getting an error of Invalid column name 'ids'
Is this possible or do I need to first run that query and then go back and run a new one for the count of the third table?
The result I need is
Table1.t1id, count(Table3.t1id)
Table3.t1id comes from Table1.t1id and all Table2.t1id_Child relation through Table1.t1id = Table2.t1id_Parent
I guess not possible, but got it partially working with CTE, I am now getting the list of say I have this '15673,15690,90987,45058' I can then do the query for the third column but getting the error
WITH items AS
(
select
a.ItemID,
stuff(
(select ',' +
CAST(
CASE WHEN b.[ChildItemID] is not null
THEN b.[ChildItemID] ELSE 0 END AS varchar)
from Table2 t2
where t2.[ParentItemID] = a.ItemID
for xml path('')
),1,2,'')
select
items.*,
docs.docs_count
from items
LEFT OUTER JOIN (
select count([DocID]) as docs_count from Table3
group by DocID
) as docs ON docs.ItemID in (items.ItemID)
Conversion failed when converting the nvarchar value '15673,' to data type int.
Note that the issue is not concatenating, I am getting the result expected there, a comma separated list of values, the issue comes when I try to use the comma separated values in "as docs ON docs.ItemID in (items.ItemIDs)"

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

Applying outer layer that wrapping two select statement

I have two query which has successfully inner join
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
The above query will return me the name and the corresponding number of count and the sum. I need to do a comparison between the count and sum. If the count doesnt match the sum, it will return 0, else 1. And so my idea was implementing another outer layer to wrap them up and use CASE WHEN. However, I've failed to apply an outer layer just to wrap them up? This is what I've tried:
select * from(
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
)
Alright the problem can be solved by simply assigning a name to the outer layer.
select * from(
select t1.countResult, t2.sumResult from (
select
count(column) as countResult
from tableA join tableB
on tableA.id = tableB.id
group by name
)t1 inner join (
select
sum(column) as sumResult
from tableA
join tableB
on tableA.id = tableB.id
group by name
)t2
on t1.name= t2.name
) as whatever //SQL Server need a name to wrap
Hope it will help any newbie like me
Ok, so far you have selected everything your first select has generated (kinda useless, but a start for what you want ;) )
SELECT CASE
WHEN countresult=sumresult THEN 'Equal'
ELSE 'Not'
END
FROM ( --your join select --
)
I don't have any sample data to test this so can just go on your code.
Your queries for t1 & t2 look identical - why don't you just do a sum & count in 1 step?
SELECT COUNT(column) AS countResult
,SUM(column) AS sumResult
FROM tableA INNER JOIN tableB
ON tableA.id = tableB.id
GROUP BY name
Also, as you mention you are a newb - read up on Common Table Expressions in SQL Server.
Before SQL 2005 you had to write these convoluted queries within queries within...
Get into the habit of using CTEs now.

Determine table to join based on the condition

I am not sure if I've missed to search properly, but I couldn't get the exact question as mine
This is something similar but not exact
https://stackoverflow.com/questions/11533636/determining-which-table-to-join-to
Actually I want to decide with which table to join based on the parameter passed to stored procedure, case when didn't work
Kind of
select * from Table1
left join (case when #Parameter<>NULL Then Table2 else Table3 end) final
on Table1.Col1 = final.Col1
Table2 and Table3 has same structure
I can think of a few of options:
1: IF ... ELSE
IF #Parameter IS NULL
SELECT *
FROM T1
INNER JOIN T2 ON T1.ID = T2.ID
ELSE
SELECT *
FROM T1
INNER JOIN T3 ON T1.ID = T3.ID
2: Dynamic T-SQL
DECLARE #SQL NVARCHAR(MAX);
SELECT #SQL = N'SELECT *
FROM T1
INNER JOIN ' + CASE WHEN #Parameter IS NULL THEN N'T2 t' ELSE N'T3 t' END
+ N' ON T1.ID = t.ID';
EXEC sp_executesql #SQL;
3: UNION ALL and subquery.
SELECT *
FROM T1
INNER JOIN
(
SELECT *
FROM T2
WHERE #Parameter IS NULL
UNION ALL
SELECT *
FROM T3
WHERE #Parameter IS NOT NULL
) t ON T1.ID = t.ID
For this last one you'd have to check the plan the optimiser creates to see if it's OK performance wise.
It seems like you're looking for code reuse, so maybe option 2 is your best one. T-SQL doesn't really lend itself to this sort of polymorphism but you can use workarounds in some cases.
Taking a step back, one question to ask is, if the tables have the same structure, maybe you should just use one table? Then you could use #Parameter to just filter the rows you require instead of trying to create dynamic queries.
It's also worth noting that in situations like this you could handle the code-generation at the application layer with ORMs and the like.
Try this:
select *
from (
select data.*,
case when selection=1 then t1.ExtraField
when selection=2 then t2.ExtraField
when selection=3 then t3.ExtraField
else NULL
end as ExtraField
from data
left join t1 on t1.key = data.key and selection=1
left join t2 on t2.key = data.key and selection=2
left join t3 on t3.key = data.key and selection=3
) T
where ExtraField is not NULL
Done with this
SELECT PA.`module_id` as usertype, PA.module_pk_id, (
CASE PA.`module_id`
WHEN '0'
THEN pea.`name`
ELSE CONCAT(u.`first_name`, " ",u.`last_name`)
END
) as name
FROM `placements_approvers` PA
LEFT JOIN
placements_external_approvers pea
ON
PA.module_pk_id = pea.placement_external_approver_id AND PA.`module_id` = 0
LEFT JOIN
users u
ON
PA.module_pk_id = u.user_id AND PA.`module_id` != 0
WHERE PA.placement_id = '494' AND PA.approver_type = 1

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