How to check if a field exists in SQL subquery? - sql

I have to do a lot of queries with this kind of logic:
Check if a table contains a record for a patient
If it does return then 'Yes'
Else return 'No'
Now, I want to create a procedure that will do this, so I tried to create a function that will do the above, but ended up in dynamic queries which is not possible in functions.
Is it possible to achieve this? How can I go about this?
PS:
Maybe something like:
select
(IF EXISTS(SELECT * FROM Dtl_Patient WHERE Pk = 3990 select 'Yes' else select 'No')) as output from dtl_AllPatient;

Try CASE
SELECT
CASE WHEN EXISTS (SELECT PatientID FROM Table2 T2 WHERE T2.PatientID =T1.PatientID)
THEN 'YES' ELSE 'NO' END AS PatientExists
FROM
Table1 T1
EDIT
SELECT
CASE WHEN EXISTS (SELECT Pk FROM Dtl_Patient WHERE Pk = 3990) THEN 'YES' ELSE 'NO' END AS PatientExists
FROM dtl_AllPatient
check this EXISTS Condition
The SQL EXISTS condition is considered "to be met" if the subquery returns at least one row.

Related

Use of CASE with criteria from multiple tables

I have to do a select query to create a view with specific criteria.
I have multiple tables which contains many many columns and lines.
However, I have extracted a value to use as my key (e.g.: id). I have 7000+ of those unique keys that I extracted from all my tables with the function UNION to avoid duplicates.
Now, I want to add a column INDICATOR_1 which will affect the value YES or NO based on criteria.
This is where I struggle.
I need to find the line in those tables that contain the id. After that, I'd like to check, always in that line, if the field XYZ contains the value 'N' (example). If yes, affect the value 'YES' to INDICATOR_1, else it's no.
In a matter of pseudo-code, what I want to do looks like this :
CASE
WHEN id = (id from table_1) AND (if table_1.xyz = 'N')
THEN 'YES'
ELSE 'NO'
END AS INDICATOR_1
I don't know if I'm clear enough, but your help will be greatly appreciated.
If I understand correctly, you want a separate indicator for each table. Something like this:
select i.*,
(case when exists (select 1
from table1 t1
where t1.id = i.id and t1.xyz = 'N'
)
then 'YES' else 'NO'
end) as indicator_1,
(case when exists (select 1
from table2 t2
where t2.id = i.id and t2.xyz = 'N'
)
then 'YES' else 'NO'
end) as indicator_2,
. . .
from (<your id list here>) i
I think you should fix this in the union, where you have all the data you need. You probably have something like:
SELECT Id
FROM table_1
UNION
SELECT Id
FROM table_2
How about selecting the information you want as well (I use distinct here to clarify):
SELECT DISTINCT Id
, CASE WHEN table_1.xyz = 'N' THEN 'N'
ELSE 'Y'
END INDICATOR_1
FROM table_1
This can lead to more records than you had, if id's can have records of both flavours exist. We can fix that with a row number in an outer query. You end up with something like:
SELECT Id
, INDICATOR_1
FROM (
SELECT Id
, INDICATOR_1
, ROW_NUMBER()OVER(PARTITION BY ID ORDER BY CASE WHEN INDICATOR_1 ='N' THEN 0 ELSE 1 END) RN
FROM (
SELECT Id
, CASE WHEN table_1.xyz = 'N' THEN 'N'
ELSE 'Y'
END INDICATOR_1
FROM table_1
UNION
...
) T
) S
WHERE S.RN = 1
You can in fact shorten that by using the inner most case expression in the ROW_NUMBER expression.

How to merge same table with different conditions

I need to write a query to produce a result to display the OLD_ACCOUNT_ID when available else NULL and the NEW_ACCOUNT_ID when available else NULL from the same table based on the conditions. I tried a query like below but this does not produce the data in separate columns as OLD and NEW. Can somebody please help.
SELECT DISTINCT
A.ACCOUNT_ID as NEW_ACCOUNT_ID,
A.ACTIVE_FLAG,A.DATA_ID
FROM Table A
WHERE DATA_SOURCE_PROVIDER_ID='X'
AND ACTIVE_FLAG='Y'
and DATA_ID= '12345678'
union
SELECT DISTINCT B.ACCOUNT_ID AS OLD_ACCOUNT_ID,
B.ACTIVE_FLAG,B.DATA_ID
FROM Table B
WHERE DATA_SOURCE_PROVIDER_ID='X'
AND ACTIVE_FLAG='N'
and DATA_ID= '12345678'
Use case
select DISTINCT
case ACTIVE_FLAG when 'Y' then ACCOUNT_ID end as NEW_ACCOUNT_ID,
case ACTIVE_FLAG when 'N' then ACCOUNT_ID end as OLD_ACCOUNT_ID,
ACTIVE_FLAG,D
DATA_ID
from Table
whene DATA_ID= '12345678';

How to use CASE without adding new column to table in SQL

How to change column value by CASE command depending on condition without giving adding a new column to table?
The only way I know is by adding new column:
SELECT
t1.*
,CASE
what='costs' THEN amount*(-1)
ELSE
sales
END AS NewAmount
FROM t1
Is there a way to get the results as on the picture below? Note that sometimes the condition is specified by values in more than one column (what=costs AND country=Atlantida)
Select just the columns that you want:
SELECT t1.what,
(CASE WHEN what = 'costs' THEN amount*(-1)
ELSE sales
END) AS Amount
FROM t1
Yes, there is way,
Instead of select *, use required column names only.
SELECT
t1.what
,CASE
WHEN what='costs' THEN amount*(-1)
ELSE
sales
END AS Amount
FROM t1
Don't you want amount when not cost?
SELECT
t1.*
,CASE when what='costs' THEN amount*(-1)
ELSE
amount
END AS NewAmount
FROM t1

If at least one record has value 1 then return 'Yes'

I have a table in SQL Server that contains a column yesno.
If at least one of the rows has the column yesno=1 then I need to return only one row yes.
I made a query that returns for every row if is yes or no.
(select (case when isnull(coalesce(dl.yesno,'2'),'2')='1' then 'Yes' else 'NO' END)
from table dl where dl.ID='A5454322-C239-4FF2-A458-8A9BD79C1839')
select 'yes'
where exists (select 1 from the_table where yesno = '1');
SQLfiddle example: http://sqlfiddle.com/#!3/069204/1
select 'yes' where exists (select * from MyTable where [yesno]='1')
select top 1 'yes' from table where yesno = 1

How to summarize SQL table to return value conditionally

I have a table with several rows, and several columns. It looks like this:
Name Description
X PASS
X PASS
X FAIL
I want it to return only one row. If all of them are PASS, return PASS.
If one or more of them are FAIL, then return FAIL.
What's the best way to go about achieving this in SQL Server 2008?
EDIT: The values in the name column will always be the same.
Depending on the database indexes, and assuming you want one row returned per unique name, I would look at the performance of
select
name,
min([description]) as description
from
tableA
group by
name
compared to the other solutions
SELECT TOP 1 CASE Description WHEN 'FAIL' THEN 'FAIL' ELSE 'PASS' END
FROM DaTable
ORDER BY Description
OP: Is it possible that the table is empty? In that case this query won't return any rows, obviously.
EDIT
According to aquinas's comment I created a modified query without ordering:
SELECT CASE COUNT(Description) WHEN 0 THEN 'FAIL' ELSE 'PASS' END
FROM DaTable
WHERE Description = 'FAIL'
This query will return PASS if DaTable is empty.
This is the simplest solution you will find:
SELECT MIN(Description) FROM tbl
If there's at least one FAIL, then our result column will contain FAIL, otherwise, it will contain PASS.
You can use EXISTS to get the existance of a row containing "FAIL".
You could also try something like:
SELECT TOP 1 COALESCE(tFail.Description,t.Description)
FROM myTable AS t
LEFT JOIN myTable AS tFail ON tFail.Name = t.Name AND tFail.Description = 'FAIL'
WHERE t.Name = 'x'
Here is the query:
--DROP TABLE result
CREATE TABLE result(Name varchar(10),Description varchar(20))
--select * from result
INSERT INTO result
VALUES('X','PASS'),('X','PASS'),('X','FAIL')
;WITH CTE(descp,cnt) as (SELECT [description],COUNT(*) as cnt FROM result group by [description])
SELECT CASE WHEN COUNT(*) > 1 then 'FAIL' when COUNT(*)=1 then MAX(descp) else 'PASS' END FROM CTE