Compare 1 field from sub query against other? - sql

I am trying to compare two fields in oracle select query as part of case statement one of which is coming from sub query but I get error.
E.g
select 1 as one,
(select 2 from dual) as two,
case when one=two then 'EQUAL'
else 'NOTEQUAL'
end match
from dual;
Error ORA-00904: TWO invalid identifier
Thoughts how can rewrite this?
Thanks in advance!

You cant use the alias, so you have to rewrite the data source and subquery.
SELECT 1 as one,
(SELECT 2 FROM dual) as two,
CASE WHEN 1 = (SELECT 2 FROM dual)
THEN 'EQUAL'
ELSE 'NOTEQUAL'
END match
FROM dual
Result
one two match
1 2 NOTEQUAL

The problem is you cant use the alias on the same level, you need to do a subquery or a cte
WITH step1 as (
select 1 as one
from dual
), step2 as (
select 2 as two
from dual
)
SELECT case when one=two then 'EQUAL'
else 'NOTEQUAL'
end match
FROM step1
CROSS JOIN step2

Use a simple subquery
Select t.*,
case when one=two then 'EQUAL'
else 'NOTEQUAL'
end match
From (
select 1 as one,
(select 2 from dual) as two
from dual
) t;

Related

Oracle: Handling Null In Case Statement

I have a huge query used within a case-when block.
My query looks like this:
SELECT 'TEST' FROM DUAL WHERE 1=1 AND EXISTS(
SELECT
CASE
WHEN EXISTS
(Select 1 from dual where 1=2)
THEN 1
ELSE
(Select 1 from dual where 1=2)
END
FROM DUAL);
I want to execute my select-statement only if the case-when statement returns a record. However, it always prints 'Test' because this code always return a NULL:
SELECT
CASE
WHEN EXISTS
(Select 1 from dual where 1=2)
THEN 1
ELSE
(Select 1 from dual where 1=2)
END
So basically I want to print "TEST" only if no record (or null value) is returned. How can I achieve this?
A row with one column that has a NULL value is not the same as a non-existing row. So, you cannot do exactly what you want using EXISTS. One method is to do:
SELECT 'TEST'
FROM DUAL
WHERE 1 = 1 AND
1 = (SELECT CASE WHEN EXISTS(Select 1 from dual where 1=2)
THEN 1
ELSE 0
END
FROM DUAL
);
That is, look for a particular value, rather than check for the existence of a row.
We can use the following to handle the NULL
CASE TRIM(Your Field) IS NULL
THEN 'The value you want to show/ print'

SQL, return select results with different where clauses

I have table whose column is just the length of a session and I would like to return the number of session that have zero length and the number of sessions that have length greater than zero.
I can do that with two separate commands
select count(session_length) from my_table where session_length=0
select count(session_length) from my_table where session_length>0
But I would like to see the results combined in one table
You can do it with one query using conditional aggregation.
select
count(case when session_length = 0 then 1 end),
count(case when session_length > 0 then 1 end)
from my_table
select 1 as QryNo, count(session_length) as SessLen
from my_table
where session_length=0
union
select 2 as QryNo, count(session_length) as SessLen
from my_table
where session_length>0
or
select
case
when session_length = 0 then 1
else 2
end as QryNo,
count(session_length) as SessLen
from my_table
This may be too simple so apologies if I have misread your query but Can you use
select count(session_length) from my_table where session_length >= 0
Again, Apologies if this is not what you're looking for.

Can Oracle PL/SQL CASE statement include a SELECT query?

I'm trying to do something similar to this:
CASE
WHEN number IN (1,2,3) THEN 'Y' ELSE 'N' END;
Instead I want to have a query in the place of the list, like so:
CASE
WHEN number IN (SELECT num_val FROM some_table) THEN 'Y' ELSE 'N' END;
I can't seem to get this to work. Also, here is an example of the query.
SELECT number, (CASE
WHEN number IN (SELECT num_val FROM some_table) THEN 'Y' ELSE 'N' END) AS YES_NO
FROM some_other_table;
Yes, it's possible. See an example below that would do what you are intending. The difference is that it uses EXISTS instead of IN.
SELECT a.number,
(CASE WHEN EXISTS (SELECT null FROM some_table b where b.num_val = a.number)
THEN 'Y'
ELSE 'N'
END) AS YES_NO
FROM some_other_table a;
EDIT:
I confess: I like the answers given by the others better personally.
However, there will be a difference between this query and the others depending on your data.
If for a value number in the table some_other_table you can have many matching entries of num_val in the table some_table, then the other answers will return duplicate rows. This query will not.
That said, if you take the left join queries given by the others, and add a group by, then you won't get the duplicates.
I suggest using an OUTER JOIN instead of trying to use a subquery in a CASE expression:
SELECT t.NUMBER,
CASE
WHEN s.NUM_VAL IS NOT NULL THEN 'Y'
ELSE 'N'
END AS YES_NO
FROM SOME_OTHER_TABLE t
LEFT OUTER JOIN SOME_TABLE s
ON s.NUM_VAL = t.NUMBER
Best of luck.
Seems like you just need to join the tables and do a decode.
with x as
(
select 1 as num from dual
union
select 2 as num from dual
union
select 3 as num from dual
),
y as
(
select 1 as num from dual
union
select 2 as num from dual
union
select 4 as num from dual
)
select x.num, decode(y.num, null, 'N','Y') as yes_no
from x
left outer join y on (x.num = y.num)
Output:
NUM YES_NO
1 Y
2 Y
3 N
You can use subquery in case statement:
select
case dummy
when 'X' then (select 'TRUE' from dual)
else 'FALSE'
end TEST
from dual;
TEST
TRUE
select
case (select 'XXX' from dual)
when 'XXX' then 'TRUE'
else 'FALSE'
end TEST
from dual;
TEST
TRUE

how fast ist it in sql if I would select only the first row with four selects

I'v a problem with look like the same as Union Select Only One Row
But with little different. I'v four selects combined with the union statment.
select top 1 value from (
select 1 as id, value from resource where rkey = 'a'
union
select 2 as id, value from resource where rkey = 'b'
union
select 3 as id, value from resource where rkey = 'c'
union
select 4 as id, value from resource where rkey = 'd'
) as x
order by id
Each of the select statement gives only one or zero rows back. I already would use the first result of all selects. So if the first select returns one row then the other selects should be ignored. And if the second select gives the row back (the first select gives no row back) then the others should be ignored. etc...
My question is: How fast is it in this combination or is there a faster solution?
Or skip the UNION:
select top 1 value
from resource
where rkey in ('a','b','c','d')
order by rkey
If key is indexed your approach (but using UNION ALL) might be the best.
Otherwise try:
select top 1 value
from resource
where rkey in ('a', 'b', 'c', 'd')
order by
case rkey
when 'a' then 1
when 'b' then 2
when 'c' then 3
when 'd' then 4
end

Referring to results of a sub query in main query

I have a sub query that returns one column, showing as GroupType, I then want to do a CASE function on this result within the main query, however I get an invalid column name when using the CASE statement.
Can i do this in SQL to do I have to refer to it by a different name
SELECT CASE
WHEN
(
SELECT column
FROM othertable
) = 1
THEN '1'
ELSE '2'
END
FROM mytable
To reuse the subquery result:
SELECT subvalue, CASE subvalue WHEN 1 THEN 1 ELSE 2 END
FROM (
SELECT (
SELECT column
FROM othertable
) AS subvalue
FROM mytable
) q