Is it possible to do a Select statement within a Case statement - sql

Is something like this possible?
SELECT WH_ACC_NO,
CASE
WHEN FIELD2 IN (SELECT * FROM TABLEB)
THEN 'PASS'
ELSE 'FAIL'
END
FROM TABLEA

FIELD2 should be mapped with TABLEB then you can do :
SELECT ta.WH_ACC_NO,
(CASE WHEN tb.FIELD2 IS NOT NULL
THEN 'PASS'
ELSE 'FAIL'
END)
FROM TABLEA ta LEFT OUTER JOIN
TABLEB tb
ON tb.FIELD2 = ta.FIELD2;
I have used FIELD2 with TABLEB, you can correct the ON clause with correct column name.

The syntax for a SELECT within CASE is a bit limited in Teradata, you need to write a Correlated Scalar Subquery to avoid the 3771 Illegal expression in WHEN clause of CASE expression error:
SELECT WH_ACC_NO,
CASE -- when FieldWhatever is not unique this shuld be MAX(FieldWhatever)
WHEN FIELD2 = (SELECT FieldWhatever FROM TABLEB AS b WHERE a.Field2 = b.FieldWhatever)
THEN 'PASS'
ELSE 'FAIL'
END
FROM TABLEA AS a

This does work normally. Code in the example below.
declare #t1 table (num int)
insert into #t1 select 1
insert into #t1 select 2
declare #t2 table (value nvarchar(10), broj int)
insert into #t2 select 'test1', 1
insert into #t2 select 'test2', 3
select case when broj in (select num from #t1) then 'good' else 'bad' end
from #t2

Yes, you can.
I tested this using the following:
select top 50 ID, Name, DOB
into #Population
from Table1
select CASE
when ID in (select ID from #Population)
then 1
else 0
end as Number
from #Population
I am sure there are limitations but this should answer your question.
Good Luck!

One thing you should know that you can't type the * in the inner query because it will return more than one result.so here is the solution.
SELECT ta.WH_ACC_NO,
(CASE WHEN tb.FIELD2 IS NOT NULL
THEN 'PASS'
ELSE 'FAIL'
END)
FROM TABLEA ta JOIN
TABLEB tb
ON tb.FIELD2 = ta.FIELD2;

Related

Oracle SQL - implement logic based on CASE expression result

I have following query which returns me of percentage of rows with at least one NULL in any of columns:
SELECT
(SUM(CASE WHEN tablea.test IS NULL OR tableb.test IS NULL THEN 1 ELSE NULL END)/7000)*100) "at least one NULL (%)"
FROM tablea
FULL OUTER JOIN tableb
ON
tablea.test = tableb.test
WHERE ROWNUM < 7000;
Query works fine to me and I am getting valid result.
But I need to do further action in tablec, based on percentage calculated in my SELECT statement. If percentage of rows with NULL is below 30% I need to insert "YES" string inside table "tablec" column "resultcol", how can I implement such a logic?
Is it for example possible to store SELECT statement result in some temporary variable which will be used in another SQL query?
You can use:
INSERT INTO tablec (resultcol)
SELECT 'YES'
FROM tablea
FULL OUTER JOIN tableb
ON tablea.test = tableb.test
WHERE ROWNUM < 7000
HAVING COUNT(CASE WHEN tablea.test IS NULL OR tableb.test IS NULL THEN 1 END)
< COUNT(*) * 0.3;
db<>fiddle here
Update:
If you want to insert a row if it does not exist or change the row if it does exist then:
MERGE INTO tablec dst
USING (
SELECT CASE
WHEN EXISTS (
SELECT 1
FROM tablea
FULL OUTER JOIN tableb
ON tablea.test = tableb.test
WHERE ROWNUM < 7000
HAVING COUNT(CASE WHEN tablea.test IS NULL OR tableb.test IS NULL THEN 1 END)
< COUNT(*) * 0.3
)
THEN 'YES'
ELSE 'NO'
END AS resultcol
FROM DUAL
) src
ON (1 = 1)
WHEN NOT MATCHED THEN
INSERT (resultcol) VALUES (src.resultcol)
WHEN MATCHED THEN
UPDATE SET resultcol = src.resultcol;
Or, to just update it:
UPDATE tablec
SET resultcol = CASE
WHEN EXISTS (
SELECT 1
FROM tablea
FULL OUTER JOIN tableb
ON tablea.test = tableb.test
WHERE ROWNUM < 7000
HAVING COUNT(
CASE
WHEN tablea.test IS NULL
OR tableb.test IS NULL
THEN 1
END
) < COUNT(*) * 0.3
)
THEN 'YES'
ELSE 'NO'
END;
db<>fiddle here

How to return true if two same columns in two different tables have values? SQL

Back on here with another question for y'all!
So we have two Pivot tables, Table_A and Table_B. Both tables have the same columns.
I was trying to write a query that'll go through each row and return true ONLY AND ONLY IF the record with the same ID has a value in the 'Value' field.
So for example, Table_A has 'sdnbfsj' value for record ID3 and Table_B has a value under the 'Value' field for the same record ID.
The query should be able to validate that the same cell in both tables have values and if they do, then return true. If the tables only had three records in total, this would have returned true but notice that record ID 5 has a value in Table_A but record ID 5 is NULL in Table_B. SO the query should return false.
This is what I have so far:
SELECT source_column from
(
select source_column from Table_A WHERE Value_Inserted=1
EXCEPT
select source_column from Table_B WHERE Value_Inserted=1
)X
WHERE source_column IN
(
'Col_1'
,'COl_2'
,'Col_3'
,'Col_4'
)
You should be able to do this by first Joining the two tables on id and then counting based on your condition. Then... return "true" or "false"
SELECT CASE WHEN SUM(CASE WHEN t1.value IS NOT NULL AND t2.value IS NOT NULL THEN 1 ELSE 0 END) = Count(*) THEN 'True' ELSE 'False' END as test
FROM table_a as t1
INNER JOIN table_b as t2 ON
t1.id = t2.id
Syntax may differ depending on what RDBMS you use.
I think you want:
select min(case when a.value is not null and a.value is null then 0
when a.value is null a and a.value is not null then 0
else 1
end) as flag
from a join
b
on a.class = b.class and a.source_col = b.source_col;
This treats 1 as true and 0 as false.
Depends on the DBMS that you're using ;
For Oracle use nvl2 function :
select nvl2(a.value, 1, 0) * nvl2(b.value, 1, 0)
from Table_A a
inner join Table_B b
on (a.ID = b.ID);
For MSSQL convert or cast functions might be used :
select convert(int, ( case when IsNull(a.value,'0') = '0' then '0'
else '1'
end ))
*
convert(int, ( case when IsNull(b.value,'0') = '0' then '0'
else '1'
end )) as result
from Table_A a
inner join Table_B b
on (a.ID = b.ID);
For MySQL use IfNull function :
select ( case when IfNull(a.value,'0') = '0' then '0'
else '1'
end )
*
( case when IfNull(b.value,'0') = '0' then '0'
else '1'
end ) as result
from Table_A a
inner join Table_B b
on (a.ID = b.ID);
For PostGreSQL use coalesce function :
select cast( ( case when coalesce(a.value,'0') = '0' then '0'
else '1'
end ) as int )
*
cast( ( case when coalesce(b.value,'0') = '0' then '0'
else '1'
end ) as int ) as result
from Table_A a
inner join Table_B b
on (a.ID = b.ID);
All of them give the following results
result
0
0
1
0
0

Checking whether two tables have identical content

How can I check and store in variable whether two tables have identical content?
I have table variable with data like
declare #table1 table (id int)
insert into #table1 (id) values (1), (2), (3)
and as the second table I have query
select T.id from SomeTable T
inner join #table1 T1 on T.id = T1.id
the query returns data:
id
-----
1
2
In this case I need write false(0) into declare #HasAccess BIT variable.
When the query returns data:
id
-----
1
2
3
then I need write true(1) into #HasAccess
Hmmm. There are various ways.
Given that you have one column, you can do:
select (case when count(*) = 0 then 1 else 0 end)
from t1 full join
t2
on t1.id = t2.id
where t1.id is null or t2.id is null;
This checks if an id doesn't match in either table.
Another way uses union all:
select (case when count(*) = 0 then 1 else 0 end)
from (select id, sum(in_t1) as num_t1, sum(in_t2) as num_t2)
from ((select id, 1 as in_t1, 0 as in_t2 from table1) union all
(select id, 0, 1 from table2)
) tt
group by id
) tt
where num_t1 <> 1 or num_t2 <> 1;
Another option (just for fun). This will compare the entire table fields and values.
I suspect not the best option for LARGE tables
Example
Select IsIdentical = case when (Select * from Table1 Order by id For XML Raw)
= (Select * from Table2 Order by id For XML Raw)
then 1 else 0 end
EDIT - Option with Inner Join
Select IsIdentical = case when (Select * from #Table1 Order by id For XML Raw)
= (Select A.*
From SomeTable A
Join #Table1 B on A.ID=B.ID
Order By id For XML Raw)
then 1 else 0 end
Using EXCEPT:
SET #HasAccess = ISNULL(
( SELECT 0
WHERE EXISTS(
SELECT ID /* add more columns here if needed */
FROM #table1
EXCEPT
SELECT ID /* add more columns here if needed */
FROM SomeTable )), 1 )
Explanation:
Return all IDs from #table1, except those found in SomeTable
Return 0 (false) if any records have been returned by [1].
If no records returned by [1] the main query will return NULL, hence the ISNULL
Advanatages
Can easily be extended to comparisons on more than one column.

Account # in SQL Tables

I want to find if an account number is in 2 different tables (SQL 2005). If it is in table A I want to pull a value from it and if it is in table B I want to do the same. The account number should be in either table but not both.
Ex. If in Table A, select the account name else if in table B select the account date
This is what I have tried so far:
SELECT a.AccountNumber
, CASE WHEN d.AccountNumber IS NULL THEN 'Yes' ELSE 'No' END AS Status
FROM tableA a
LEFT JOIN
(
SELECT *
FROM tableB b
UNION
SELECT *
FROM tableC c
WHERE AccountNumber NOT IN
(
SELECT AccountNumber FROM c
)
) d
ON a.Account = b.AccountNumber
But if it is always true that account number may exist in one of the two tables and you are selecting similar columns, you can do something like below as well
SELECT Col1,Col2,Col3
FROM TABLEA
WHERE AccountNo=#AccNo
UNION
SELECT Col1,Col2,Col3
FROM TABLEB
WHERE AccountNo=#AccNo
Or you can try the long approarch
DECLARE #Contains BIT=0,
#AccNo INT=234589
SELECT #Contains =1
FROM TABLEA
WHERE AccountNo=#AccNo
IF(#Contains=1)
BEGIN
SELECT *
FROM TABLEA
WHERE AccountNo=#AccNo
END
ELSE
BEGIN
SELECT *
FROM TABLEB
WHERE AccountNo=#AccNo
END
Try putting the JOIN in the right place:
SELECT CASE WHEN a.AccountNumber IS NULL
THEN 'Not in Table A'
WHEN b.AccountNumber IS NULL Then ' Not in Table B'
END AS 'Status'
FROM TableA a
INNER JOIN TableB b
ON b.AccID = a.AccID
WHERE AccountNumber = '234598'

TSQL/SQL 2005/2008 Return Row from one table that is not in othe table

I have to compare a row of one table that is not in another table
TableA
ID
1
2
3
4
NULL
TableB
ID
1
4
When comparing TableA with TableB ,the following o/p (NULL Can be ignored)
ID STATUS
1 FOUND
2 NOT FOUND
3 NOT FOUND
4 FOUND
I tried with
SELECT
case T.ID when isnull(T.ID,0)=0 then 'NOT FOUND'
case T.ID when isnull(T.ID,0)<>0 then 'FOUND'
end,T.ID
FROM
TableA T
LEFT JOIN
TableB N
ON T.ID=N.ID
Its ended with incorrect syntax near '=',moreover i have no idea whether the query is correct.
Try this:
SELECT a.ID,
CASE WHEN b.ID IS NULL THEN 'NOT FOUND' ELSE 'FOUND' END AS Status
FROM TableA a
LEFT JOIN TableB b ON a.ID = b.ID
Note the difference in the structure of the CASE statement - that was your problem.
To generate the result as shown in the question:
SELECT ID,
CASE WHEN EXISTS (SELECT * FROM TableB WHERE ID = TableA.ID)
THEN 'FOUND'
ELSE 'NOT FOUND'
END AS STATUS
FROM TableA
But if you are only interested in the missing records:
SELECT ID
FROM TableA
WHERE NOT EXISTS (SELECT * FROM TableB WHERE ID = TableA.ID)
SELECT
T.ID
FROM TableA T WHERE NOT EXISTS ( SELECT X.ID FROM TableB X WHERE X.ID = T.ID)
If you want the 'Found' or 'Not Found' answer go for what AdaTheDev posted