How to merge same table with different conditions - sql

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';

Related

How to create a new column based on data out from a query

I have a quick question.
ATtaching the SS for reference.
How can i set a new column 'Status' as NO based the nvl condition if the id is null then i have to map to the corresponding of another table .
You can do that using case statement.
select
nvl(b.id,a.id) as id
,b.name
,case when nvl(b.id,a.id) is null then 'No' else 'Yes' End as Status
from dd b,
(select id, name from demo group by id, name)a
where a.id=b.id(+)

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.

SQL AND Clause only if another value exists

I have a basic SQL query where I am selecting data from a core records table. I want to add an AND clause to my statement to filter out the results based on a table variable, only if data actually exists in there.
SELECT
*
FROM
TABLE
WHERE
field = '123'
AND
(gender IN (SELECT gender FROM #genders))
In this case, I am looking for all records where field = 123. My goal here is to say that if #genders contains records, filter by that as well.
However, if #genders is empty and we don't have any data in it, it should include all records.
How can I go about doing this? The temp tables are created based on the user selecting one or more optional pieces of criteria from the UI. If they choose a gender for example, I put their selections into a temp table and then I need to search records that meet that criteria. However, if they don't select a gender, I want to include all records, regardless of what the main record has for the gender field.
SELECT
*
FROM
TABLE
WHERE
field = '123'
AND ((SELECT count(1) FROM #genders) = 0 OR
(gender IN (SELECT gender FROM #genders)))
You can use IF condition:
IF EXISTS(SELECT gender FROM #genders)
BEGIN
SELECT * FROM TABLE
WHERE field = '123'
AND
(gender IN (SELECT gender FROM #genders))
END
ELSE
BEGIN
SELECT * FROM TABLE
END
You are going to think this is odd but it is efficient
SELECT t.*
FROM TABLE t
JOIN GENDERS g
on g.gender = t.gender
and t.field = '123'
union all
SELECT t.*
FROM TABLE t
where not exists (select 1 from genders)
Maybe I'm under-thinking it, but isn't it just this?
SELECT
*
FROM
TABLE AS t
LEFT JOIN
#genders AS g
ON
g.gender = t.gender
WHERE
field = '123'
AND
(g.gender = t.gender OR g.gender IS NULL);
If your query doesn't get too complicated, I'd recommend an if statement. Once you find yourself continually adding if else statement in there, I'd recommend looking into dynamic SQL.
IF EXISTS(SELECT gender FROM #genders)
BEGIN
SELECT * FROM TABLE
WHERE field = '123'
and gender IN (SELECT distinct gender FROM #genders)
END
ELSE
BEGIN
SELECT * FROM TABLE WHERE field = '123'
END

Joining a Temp Table to Actual Table

I need to verify that each order has been acknowledged. The problem is that each order can have multiple codes. The query I had (utilizing a CASE statement) would check for blank fields or fields with the string "None" to verify the order has not been acknowledged. It would return the appropriate result, but multiple rows (once for each possible response) and I only need (1).
I'm attempting to create a temp table that will return the appropriate result and join (via an order unique ID) the two tables together hoping to correct the multiple row issue. Here is the code:
DROP TABLE staging_TABLE;
CREATE TEMP TABLE staging_TABLE(
ORDERID varchar(256) ,
CODE varchar(256) );
/*Keeping data types consistent with the real table*/
INSERT INTO staging_TABLE
SELECT ORDERID,
CASE CODE
WHEN 'None' THEN 'No'
WHEN '' THEN 'No'
ELSE 'Yes'
END
FROM ORDERS
WHERE UTCDATE > SYSDATE - 10
AND CODE IS NOT NULL;
SELECT R.QUESTION,
R.ORDERNAME,
T.CODE
FROM ORDERS R
INNER JOIN staging_TABLE T
ON R.ORDERID= T.ORDERID
WHERE R.UTCDATE > SYSDATE - 10
AND R.CODE IS NOT NULL
AND R.CATEGORY IS NOT NULL
AND R.UTCDATE IS NOT NULL
GROUP BY
R.ORDER,
T.CODE,
R.ORDERNAME,
R.CODE
ORDER BY
R.ORDERNAME,
R.ORDER;
Am I doing this correctly? Or is this even the right approach?
Am I doing this correctly? Or is this even the right approach?
No. You don't need a temp table for this. Your query might look like this:
SELECT question, ordername
, CASE WHEN code IN ('None', '') THEN 'No' ELSE 'Yes' END AS code
FROM orders
WHERE utcdate > sysdate - 10
AND code IS NOT NULL
AND category IS NOT NULL
GROUP BY question, ordername, 3, "order"
ORDER BY ordername, "order";
ORDER is a reserved word. It's not possible to use it as column name unless double quoted. There is something wrong there.
AND R.UTCDATE IS NOT NULL is redundant. It can't be NULL anyway with WHERE R.UTCDATE > SYSDATE - 10
3 in my GROUP BY clause is a positional reference to the CASE expression. Alternatively you can spell it out again:
....
GROUP BY question, ordername
, CASE WHEN code IN ('None', '') THEN 'No' ELSE 'Yes' END
, "order"
You can use the DISTINCT keyword as follows so you will not need a temp table:
SELECT DISTINCT QUESTION,
ORDERNAME,
CASE CODE
WHEN 'None' THEN 'No'
WHEN '' THEN 'No'
ELSE 'Yes'
FROM ORDERS
WHERE UTCDATE > SYSDATE - 10
AND CODE IS NOT NULL
AND CATEGORY IS NOT NULL
AND UTCDATE IS NOT NULL
ORDER BY 2,3;

How to check if a field exists in SQL subquery?

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.