Oracle SQL Joining 2 Queries - sql

I am trying to form a query using 2 other queries, but I don't know how I would do it exactly. I am using Oracle SQL. Here is the basic logic:
if (select supervisor_id from PS_EMPLOYEES where EMPLID = %This.sEMPLID)
is in
(select EMPLID from sysadm.PS_Z_RPT_TO_REL where Z_DIRECT_RPT = 'D' where manager_id = %EmployeeID)
return True else return False.
Basically the first query will have an ID and will search through a list formed from the second query. If the ID from the first query is in the list from the second query then return 'True' else return 'False' Any thoughts?

Something like the following perhaps (untested):
SELECT EXISTS (
SELECT supervisor_id
FROM PS_EMPLOYEES
WHERE EMPLID = %This.sEMPLID
AND supervisor_id IN (
SELECT EMPLID
FROM sysadm.PS_Z_RPT_TO_REL
WHERE Z_DIRECT_RPT = 'D'
AND manager_id LIKE %EmployeeID
)
)

Related

Returning something like error-codes from query

I want to check conditions in query. If condition is false, then query must returns error code, else query must to execute another query.
Something like that:
WITH error_code_get AS (
SELECT
CASE
WHEN NOT EXISTS (
SELECT 1
FROM users
WHERE id = '1a4b...'
) THEN 1
WHEN NOT EXISTS (
SELECT 1
FROM workspaces
WHERE id = '353...'
) THEN 2
WHEN (
SELECT settings
FROM workspace_roles
WHERE workspace_id = '353...'
AND id IN (
SELECT role_id
FROM m2m_users_to_workspace_or_projects_roles
WHERE role_type='1'
AND user_id='1a4b...'
)
) < 2 THEN 3
ELSE 0
END error_code
RETURNING error_code
)
// WRONG PART
CASE
WHEN (SELECT error_code FROM error_code_get) = 0 THEN (INSERT INTO x(a) VALUES('some_value'))
ELSE (SELECT error_code FROM error_code_get)
END
You can't do something like that in pure SQL, you'd need to write code in Stored Proc or Function

Presto Pivoting Data

I am really new to Presto and having trouble pivoting data in it.
The method I am using is the following:
select
distinct location_id,
case when role_group = 'IT' then employee_number end as IT_emp_num,
case when role_group = 'SC' then employee_number end as SC_emp_num,
case when role_group = 'HR' then employee_number end as HR_emp_num
from table
where 1=1
and id = 1234
This is fine, however, null values are also populated for the rows and I would like to pivot the data, to only return one row with the relevant info.
I have tried using the array_agg function, which will collapse the data but it also keeps the null values (e.g. it will return null,301166,null for the first colum)
If only one row per location is needed you can use max with group by:
select location_id,
max(IT_emp_num) IT_emp_num,
max(SC_emp_num) SC_emp_num,
max(HR_emp_num) HR_emp_num
from (
select location_id,
case when role_group = 'IT' then employee_number end as IT_emp_num,
case when role_group = 'SC' then employee_number end as SC_emp_num,
case when role_group = 'HR' then employee_number end as HR_emp_num
from table
where id = 1234)
group by location_id

SQL comparing each row to a reference row

I am trying to compare each row from a select statement to a reference row.
So to put it into context I would like to find the reference row which is the account details for one of our users.
SELECT id, first_name
FROM account
WHERE id = '100'
Would return the info for the user in question
Then I want to run a SELECT statement to return all users - pretty straightforward
SELECT id,first_name
FROM account
For each row I would like to compare the first_name with the reference row. If it is the same return a '1' if it is different return a '0'
I can do this if I type in the value to compare e.g 'Paul'
SELECT id,first_name,
CASE
WHEN first_name = 'Paul' THEN '1'
ELSE '0'
END
FROM account
But obviously I want to replace Paul with whatever the first_name is from the reference row above.
My googling suggests I need to declare a variable and then something with SELECT INTO a variable
DO $$;
Declare
#reference_first_name text;
BEGIN
SELECT first_name
into #reference_first_name
FROM account
WHERE id = ‘100’
END;
But I can't seem to put it together.
Then to go a step further would it be possible to reference multiple columns?
You could do this simply in a subquery:
demo:db<>fiddle
SELECT
id,
first_name,
CASE
WHEN (SELECT first_name FROM users WHERE id = 100) = first_name THEN 1
ELSE 0
END
FROM users;
Other ways are using a CTE or a JOIN (see fiddle for these versions)
Here's another option using an outer join:
select a.id, a.first_name, case when a.first_name = b.first_name then 1 else 0 end
from account a
left join account b on b.id = 100
Online Demo
Use correlated subquery as :
select a.id, a.first_name,
( select count(*)
from personnel p
where p.id = 100
and upper(p.first_name) = upper(a.first_name) ) as flag
from account a;
provided you have a table called personnel and has an ID fixed for all comparisons.
Rextester Demo

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

Select an ID if count is equal to 1

I am trying to write a query which needs to find an ID number from 3 WHERE values based on the result only being equal to 1.
So say i want to find a patient's ID and my where clause matches the firstname, lastname and DOB. If there are 2 results because of duplicates, i need the output to be NIL else it should return the patient ID.
if(select count(*)
from patient
where last_name = 'JAMES'
and first_name = 'JONES'
and birth_DtTM = '1980-01-01') > 1
print 'NULL' else return Pat_ID1
This is kind of what i am leading towards.
Thanks guys
select case when count(*)> 1
then 'NULL' else Pat_ID1 end
from patient
where last_name = 'JAMES'
and first_name = 'JONES'
and birth_DtTM = '1980-01-01'
group by Pat_ID1
try below.
;WITH CTE(Pat_ID1,last_name,first_name,birth_DtTM,dup_rows)
as
(
SELECT Pat_ID1,last_name,first_name,birth_DtTM,ROW_NUMBER() OVER(PARTITION BY last_name,first_name,birth_DtTM ORDER BY Pat_ID1) AS dup_rows FROM patient
)
SELECT
case when dup_rows>1 then null
when dup_rows=1 then Pat_ID1
end
FROM CTE
You can do it like this:
SELECT
PatientID = CASE COUNT(*) WHEN 1 THEN MAX(Pat_ID1) END
FROM
patient
WHERE
last_name = 'JAMES'
AND first_name = 'JONES'
AND birth_DtTM = '1980-01-01'
;
The CASE expression will evaluate either to the single Pat_ID1 matching the request or to NULL (if COUNT(*) is anything but 1).
As you can see, the Pat_ID1 value is obtained with the help of an aggregate function (by the way, you can use MIN instead of MAX just as well). This is because the presence of COUNT(*) in the query automatically implies grouping and now, if you want to reference columns of the underlying row set, you must only access their aggregated values.