Combine a 'Distinct' SQL Query with a single value query - sql

I have an existing sql query that I'd like to apply to every record returned from a "distinct" query.
I guess something like looping through each of the returned records, storing it as a string, and using that value in the other query. How would I go about this?
sudo queries:
Select ...
for each record returned as X,
Select ... etc ... where ... LIKE X
Edit:
not sure how to make it clearer, but I know I'm probably not making it obvious. I'll try:
The distinct will return a single column, with many records. I need to apply each value to the second sql query.
So like.. Select X and Y, but Y is returned from the 2nd query I have, using X
Edit2:
If the distinct select returns
1
2
3
4
And the second query returns a single record "A" when the where clause looks like ... = '1', "B" when the where clause looks like ... = '2', "C" when the where clause looks like ... = '3', and C when the where clause looks like ... = '4'
Then I'd like my final output to look like
1 | A
2 | B
3 | C
4 | C
Edit 3:
first query:
SELECT DISTINCT [user_id] from dbo.sap_empl_subset
second query:
SELECT [name_pref_mixed]
FROM dbo.sap_empl_subset AS E
WHERE E.sap_position_no IN
(SELECT P.sap_position_no
FROM dbo.sap_position AS P
WHERE (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%[VICE ]PRESIDENT%')
OR (LTRIM(RTRIM(P.sap_position_desc)) LIKE 'CHIEF%'))
AND E.sap_org_code =
(SELECT
CASE
WHEN S.sap_org_code_level2 = 0 THEN S.sap_org_code
WHEN S.sap_org_code_level3 = 0 THEN S.sap_org_code_level1
ELSE S.sap_org_code_level2
END
FROM dbo.sap_org_structure AS S
WHERE S.sap_org_code =
(SELECT E1.sap_org_code
FROM dbo.sap_empl_subset AS E1
WHERE E1.[user_id] = '<each item from first query needs applied here>'))

SELECT *
FROM (
SELECT DISTINCT value
FROM mytable
) x
JOIN othertable y
ON y.value LIKE '%' || x.value || '%'
Update:
If you first query is
SELECT my_x
FROM mytable
WHERE my_y = '…'
and the second one is
SELECT other_z
FROM othertable
WHERE other_y = my_x
the you just need a join:
SELECT my_x, other_z
FROM mytable
JOIN othertable
ON other_y = my_x
WHERE my_y = '…'
It would be much more easy to answer if you just posted the queries.
Update 2:
Try this:
SELECT es.user_id, esp.name_pref_mixed
FROM sap_empl_subset es
JOIN sap_org_structure os
ON os.sap_org_code = es.sap_org_code
JOIN sap_empl_subset esс
ON esc.sap_org_code =
CASE
WHEN os.sap_org_code_level2 = 0 THEN os.sap_org_code
WHEN os.sap_org_code_level3 = 0 THEN os.sap_org_code_level1
ELSE os.sap_org_code_level2
END
WHERE esc.sap_position_no IN
(
SELECT sap_position_no
FROM sap_position sp
WHERE (LTRIM(RTRIM(sp.sap_position_desc)) LIKE '%[VICE ]PRESIDENT%')
OR (LTRIM(RTRIM(sp.sap_position_desc)) LIKE 'CHIEF%'))
)
DISTINCT seems to be redundant here. You have a condition in your second query:
WHERE S.sap_org_code =
(
SELECT E1.sap_org_code
FROM dbo.sap_empl_subset AS E1
WHERE E1.[user_id] = '<each item from first query needs applied here>')
)
which would throw an error if there were duplicates on sap_empl_subset.user_id

A join was not necessary to combine the two queries. All I needed was the nested select syntax as shown below, where the first line is the first query, and the first nested select is the second query. A join was not necessary.
SELECT Distinct U.[user_id] AS "User ID", (
SELECT [empl_last_name]
FROM dbo.sap_empl_subset AS E
WHERE E.sap_position_no IN
(SELECT P.sap_position_no
FROM dbo.sap_position AS P
WHERE (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%[VICE ]PRESIDENT%')
OR (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%CHIEF%')
OR (LTRIM(RTRIM(P.sap_position_desc)) LIKE '%[EXECUTIVE ]VP%')
)
AND E.sap_org_code =
(SELECT
CASE
WHEN S.sap_org_code_level2 = 0 THEN S.sap_org_code
WHEN S.sap_org_code_level3 = 0 THEN S.sap_org_code_level1
ELSE S.sap_org_code_level2
END
FROM dbo.sap_org_structure AS S
WHERE S.sap_org_code =
(SELECT E1.sap_org_code
FROM dbo.user_id AS E1
WHERE E1.[user_id] = U.[user_id]))) As "VP"
From dbo.user_id As U WHERE U.[user_id] <> ''
ORDER BY [User ID]

Related

SQL query having CASE WHEN EXISTS statement

I trying to create a SQL query with a CASE WHEN EXISTS clause in SQL Server. I assume I am doing something wrong as when I run the SELECT * FROM [Christmas_Sale] it takes forever for SQL to load the code.
CREATE VIEW [Christmas_Sale]
AS
SELECT
C.*,
CASE
WHEN EXISTS (SELECT S.Sale_Date
FROM [Christmas_Sale] s
WHERE C.ID = S.ID)
THEN 0
ELSE 1
END AS ChristmasSale
FROM
[Customer_Detail] C ;
I'm trying to write a sub select which I need to return a 1 if Sale_Date= 1 and 0 for anything else.
The syntax of your query looks ok. But since your stated:
I'm trying to write a sub select which I need to return a 1 if Sale_Date= 1 and 0 for anything else.
... Then you could rephrase your query by adding one more condition in the WHERE clause of the subquery:
CREATE VIEW [Christmas_Sale]AS
SELECT
C.*,
CASE WHEN EXISTS (
SELECT 1
FROM [Christmas_Sale] s
WHERE C.ID = S.ID and S.Sale_Date = 1
) THEN 0 ELSE 1 END AS ChristmasSale
FROM [Customer_Detail] C ;
If a record exists in [Christmas_Sale] with the corresponding ID and Sale_Date = 1, then ChristmasSale will have value 1, else it will display 0.
This query looks correct:
CREATE VIEW [Christmas_Sale] AS
SELECT C.*,
(CASE WHEN EXISTS (SELECT 1
FROM [Christmas_Sale] s
WHERE C.ID = S.ID
)
THEN 0 ELSE 1
END) AS ChristmasSale
FROM [Customer_Detail] C ;
If performance is an issue, you want an index on Christmas_Sale(ID).
Note that the SELECT S.Sale_Date in the subquery is meaningless, because EXISTS checks for rows not columns. Hence, I replaced it with the simpler 1.

Oracle SQL XOR condition with > 14 tables

I have a question on sql desgin.
Context:
I have a table called t_master and 13 other tables (lets call them a,b,c... for simplicity) where it needs to compared.
Logic:
t_master will be compared to table 'a' where t_master.gen_val =
a.value.
If record exist in t_master, retrieve t_master record, else retrieve 'a' record.
I do not need to retrieve the records if it exists in both tables (t_master and a) - XOR condition
Repeat this comparison with the remaining 12 tables.
I have some idea on doing this, using WITH to subquery the non-master tables (a,b,c...) first with their respective WHERE clause.
Then use XOR statement to retrieve the records.
Something like
WITH a AS (SELECT ...),
b AS (SELECT ...)
SELECT field1,field2...
FROM t_master FULL OUTER JOIN a FULL OUTER JOIN b FULL OUTER JOIN c...
ON t_master.gen_value = a.value
WHERE ((field1 = x OR field2 = y ) AND NOT (field1 = x AND field2 = y))
AND ....
.
.
.
.
Seeing that I have 13 tables that I need to full outer join, is there a better way/design to handle this?
Otherwise I would have at least 2*13 lines of WHERE clause which I'm not sure if that will have impact on the performance as t_master is sort of a log table.
**Assume I cant change any schema.
Currently I'm not sure if this SQL will working correctly yet, so I'm hoping someone can guide me in the right direction regarding this.
update from used_by_already's suggestion:
This is what I'm trying to do (comparison between 2 tables first, before I add more, but I am unable to get values from ATP_R.TBL_HI_HDR HI_HDR as it is in the NOT EXISTS subquery.
How do i overcome this?
SELECT LOG_REPO.UNIQ_ID,
LOG_REPO.REQUEST_PAYLOAD,
LOG_REPO.GEN_VAL,
LOG_REPO.CREATED_BY,
TO_CHAR(LOG_REPO.CREATED_DT,'DD/MM/YYYY') AS CREATED_DT,
HI_HDR.HI_NO R_VALUE,
HI_HDR.CREATED_BY R_CREATED_BY,
TO_CHAR(HI_HDR.CREATED_DT,'DD/MM/YYYY') AS R_CREATED_DT
FROM ATP_COMMON.VW_CMN_LOG_GEN_REPO LOG_REPO JOIN ATP_R.TBL_HI_HDR HI_HDR ON LOG_REPO.GEN_VAL = HI_HDR.HI_NO
WHERE NOT EXISTS
(SELECT NULL
FROM ATP_R.TBL_HI_HDR HI_HDR
WHERE LOG_REPO.GEN_VAL = HI_HDR.HI_NO
)
UNION ALL
SELECT LOG_REPO.UNIQ_ID,
LOG_REPO.REQUEST_PAYLOAD,
LOG_REPO.GEN_VAL,
LOG_REPO.CREATED_BY,
TO_CHAR(LOG_REPO.CREATED_DT,'DD/MM/YYYY') AS CREATED_DT,
HI_HDR.HI_NO R_VALUE,
HI_HDR.CREATED_BY R_CREATED_BY,
TO_CHAR(HI_HDR.CREATED_DT,'DD/MM/YYYY') AS R_CREATED_DT
FROM ATP_R.TBL_HI_HDR HI_HDR JOIN ATP_COMMON.VW_CMN_LOG_GEN_REPO LOG_REPO ON HI_HDR.HI_NO = LOG_REPO.GEN_VAL
WHERE NOT EXISTS
(SELECT NULL
FROM ATP_COMMON.VW_CMN_LOG_GEN_REPO LOG_REPO
WHERE HI_HDR.HI_NO = LOG_REPO.GEN_VAL
)
Full outer joins used to exclude all matching rows can be an expensive query. You don't supply much detail, but perhaps using NOT EXISTS would be simpler and maybe it will produce a better explain plan. Something along these lines.
select
cola,colb,colc
from t_master m
where not exists (
select null from a where m.keycol = a.fk_to_m
)
and not exists (
select null from b where m.keycol = b.fk_to_m
)
and not exists (
select null from c where m.keycol = c.fk_to_m
)
union all
select
cola,colb,colc from a
where not exists (
select null from t_master m where a.fk_to_m = m.keycol
)
union all
select
cola,colb,colc from b
where not exists (
select null from t_master m where b.fk_to_m = m.keycol
)
union all
select
cola,colb,colc from c
where not exists (
select null from t_master m where c.fk_to_m = m.keycol
)
You could union the 13 a,b,c ... tables to simplify the coding, but that may not perform so well.

sql function case returns more than one row

Going to use this query as a subquery, the problem is it returns many rows of duplicates. Tried to use COUNT() instead of exists, but it still returns a multiple answer.
Every table can only contain one record of superRef.
The below query I`ll use in SELECT col_a, [the CASE] From MyTable
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = myTable.sysno AND A_specAttr = 'value')
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo WHERE C_superRef = myTable.sysno AND b_type = 2)
THEN 2
ELSE (SELECT C_intType FROM C
WHERE C_superRef = myTable.sysno)
END
FROM A, B, C
result:
3
3
3
3
3
3...
What if you did this? Because Im guessing you are getting an implicit full outer join A X B X C then running the case statement for each row in that result set.
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM ( SELECT COUNT(*) FROM A ) --This is a hack but should work in ANSI sql.
--Your milage my vary with different RDBMS flavors.
DUAL is what I needed, thanks to Thorsten Kettner
SELECT CASE
WHEN
EXISTS (SELECT 1 FROM A WHERE
A_superRef = 1000001838012)
THEN 3
WHEN EXISTS (SELECT 1 FROM B
INNER JOIN С ON С_ReferenceForB = B_sysNo AND C_superRef = 1000001838012 )
THEN 2
ELSE (SELECT C_type FROM C
WHERE C_superRef = 1000001838012)
END
FROM DUAL

SQL Join / Union

I have two statements that I want to merge into one output.
Statement One:
select name from auxiliary_variable_inquiry
where inquiry_idbr_code = '063'
Returns the following list of names:
Name
------------
Affiliates
NetBookValue
Parents
Worldbase
Statement Two:
select name, value from auxiliary_variable_value
where inquiry_idbr_code = '063'
and ru_ref = 20120000008
and period = 200912
Returns the following:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
I would like to have an output like this:
Name Value
-------------------
Affiliates 112
NetBookValue 225.700
Parents 0
Worldbase 0
So basically, if the second query only returns 2 names and values, I'd still like to display the complete set of names from the first query, with no values. If all four values were returned by both queries, then all four would be displayed.
Sorry I must add, im using Ingres SQL so im unable to use the ISNULL function.
You can do a left join. This ensures that all records from the first table will stay included. Where value is null, no child record was found, and we use coalesce to display 0 in these cases.
select i.name, COALESCE(v.Value,0) from auxiliary_variable_inquiry i
left join auxiliary_variable_value v
on v.inquiry_idbr_code = i.inquiry_idbr_code
and v.ru_ref = 20120000008
and v.period = 200912
where i.inquiry_idbr_code = '063'
I'd recommend a self-JOIN using the LEFT OUTER JOIN syntax. Include your 'extra' conditions from the second query in the JOIN condition, while the first conditions stay in the WHERE, like this:
select a.name, CASE WHEN b.Value IS NULL THEN 0 ELSE b.Value END AS Value
from
auxiliary_variable_inquiry a
LEFT JOIN
auxiliary_variable_inquiry b ON
a.name = b.name and -- replace this with your real ID-based JOIN
a.inquiry_idbr_code = b.inquiry_idbr_code AND
b.ru_ref = 20120000008 AND
b.period = 200912
where a.inquiry_idbr_code = '063'
if i got right, you should use something like:
SELECT i.NAME,
v.NAME,
v.value
FROM auxiliary_variable_inquiry i
LEFT JOIN auxiliary_variable_value v
ON i.inquiry_idbr_code = v.inquiry_idbr_code
WHERE v.ru_ref = 20120000008
AND v.period = 200912

Combine two different select statements, one distinct the other not

I have two selects which are required to filter data. They are not complicated:
"SELECT * FROM StevesTable t WHERE "
"t.data1 = '%s' AND "
"t.data2 = to_date('%s','DD/MM/YYYY');",
strdata1,
dtDate.Format();
and
SELECT distinct data1 FROM anothertable ftt
join table1 tab on tab.somedata = ftt.somedata
where tab.somedata = 0
and tab.someotherdata = 1
I would like to combine these two as I need to filter the returned dataset from the first select statement by the returned field in the second (ie if a record returned in the first set does not have a data1 value which is contained in the second returned set it is invalid).
I tried to union and intersect the selects but you need the same number of columns returned and that cannot happen as these are completely different tables. When I tried to simply merge them together I found it difficult as the second select statement is a distinct select whereas the first is not.
I was wondering whether I had missed a trick somewhere for combining these sorts of selects?
What you need is a SQL sub-query:
SELECT * FROM StevesTable t
WHERE t.data1 = '%s'
AND t.data2 = to_date('%s','DD/MM/YYYY')
AND t.data1 in (select distinct data1 FROM anothertable ftt
join table1 tab on tab.somedata = ftt.somedata
where tab.somedata = 0
and tab.someotherdata = 1)
There, you check that all records in the first select have a data1 value in the second set.
You can do this using an EXISTS condition:
SELECT * FROM StevesTable t
WHERE t.data1 = '%s' AND
t.data2 = to_date('%s','DD/MM/YYYY') AND
EXISTS (select null
from anothertable ftt
join table1 tab on tab.somedata = ftt.somedata
where tab.somedata = 0 and
tab.someotherdata = 1 and
ftt.data1 = t.data1)