Remove rows from SQL when "CASE ELSE" happens - sql

This is my sql query:
select case when table.field1 = 1 then 1
when table.field2 = 3 then 3
when table.field2 = 4 then 4
when table.field3 = 1 then 5
else .... Status //item name
from table
I want that in case the "else" occurs -> the row will be removed from the dataSet.
I can't use "Status" in the where clause for some reason.
Ideas?

You could use a common table expression:
with TempResult (id, status)
as
(
select primary_key_column,
case when table.field1 = 1 then 1
when table.field2 = 3 then 3
when table.field2 = 4 then 4
when table.field3 = 1 then 5
else 0
from table
)
select id
from TempResult
where status > 0

The most straitforward way is to set conditions for the fields from "when", I.e. field1=1 or field2 in (3,4) or field3=1

Related

Create a new column based on existing columns inside a case statement

Say I have this table t:
id value
1 1 10
2 2 3
3 1 55
4 1 20
5 2 98
When drawing from t I want to add a column value2 that equals value when id == 2, otherwise 0
I tried
select id, value, max(case when id = 2 then value else 0) from t
but it did not work
Not sure why you included a max in your attempt but based on your description, this is all you should need.
select id, value, case when id = 2 then value else 0 end as value2
from t;
It sounds like you want a conditional window aggregate:
select
id,
value,
max(case when id = 2 then value end) over ()
from t;

Create view with multiple case without fonction

Hello I have to make a view with oracle plsql but I dont know how can I done this wihtout create function:
I got this query
Hello I want to create view who use a query :
select unique tv.id , tv.homeid
case
when ht.hometype = 'A7DF56ZEF' then 0 --HOUSE
when ht.hometype = 'A7DF45ZEF' then 1 -- SMALLHOUSE
end as housetype ,
case
when tv.isfourk is null then 0
when tv.isfourk is not null then 1
end as isfourk
from hometable ht
join tvtable tv on ht.idtv = tv.id
where tv.homeid = 'KLL5FD5Z6'
This query return me result like this
tv.id tv.homeid housetype isfourk
A7844SD KLL5FD5Z6 1 0
A7944SD KLL5FD5Z6 1 0
A8044SD KLL5FD5Z6 1 0
I want to create a view using this query result. this query will be into the view.
The view will have only one row by tv.homeid , like this
Execpted result of the view:
TV.homeid STATE
KLL5FD5Z6 (0 or 1 or 2 or 3 or 4 or 5)
STATE case condition
IF ALL ROWS HAVE isfourk = 1 THEN 1
ELSE IF ALL ROWS WHERE housetype = 1 HAVE isfourk = 1 THEN 2
ELSE IF ONE OF THESE ROWS HAVE isfourk = 0 THEN 3
ELSE IF ONE OF THESE ROWS WHERE housetype = 1 HAVE isfourk = 0 THEN 4
ELSE 5
END as STATE
If you can help me please.
Thanks
I have summarized the query as below after clarifications. I have used your query as base and on top of that applied the case logic to build the view.
One hint , use DISTINCT instead of UNIQUE
CREATE OR REPLACE VIEW give_a_view_name
AS
SELECT homeid
, CASE
WHEN MAX(isfourk) = 1 THEN 1 --IF ALL ROWS HAVE isfourk = 1
WHEN MAX(isfourk) = 1 AND MAX(housetype) = 1 THEN 2 --IF ALL ROWS WHERE housetype = 1 HAVE isfourk = 1 THEN 2
WHEN MIN(isfourk) = 0 THEN 3 --IF ONE OF THESE ROWS HAVE isfourk = 0 THEN 3
WHEN MAX(housetype) = 1 AND MIN(isfourk) = 0 THEN 4 --IF ONE OF THESE ROWS WHERE housetype = 1 HAVE isfourk = 0 THEN 4
ELSE 5 --ELSE 5
END AS state
FROM (SELECT DISTINCT
tv.id
,tv.homeid
,CASE
WHEN ht.hometype = 'A7DF56ZEF' THEN 0 --HOUSE
WHEN ht.hometype = 'A7DF45ZEF' THEN 1 --SMALLHOUSE
END AS housetype
,CASE
WHEN tv.isfourk IS NULL THEN 0
WHEN tv.isfourk IS NOT NULL THEN 1
END AS isfourk
FROM hometable ht
JOIN tvtable tv ON ht.idtv = tv.id
WHERE tv.homeid = 'KLL5FD5Z6')
GROUP BY homeid;
Check and see if it works.

Facing problem with case when statement in a single row fetch for oracle sql

I have a single row of data as follows:
dyn1 dyn2 dyn3 chg
1 0 1 768
Now i want to write a case condition like
Case when dyn1 = 1 then 7 When dyn2=1 then 7 When dyn3=1 then 7 End
Now for this above records it is not checking the dyn3 value as it is getting dyn1 value as true.
How to handle this code?
I'll suppose that you need to return those values in a select statement, maybe this could be helpful to you.
SELECT CASE WHEN dyn1 = 1 THEN 7 END,
CASE WHEN dyn2 = 1 THEN 7 END,
CASE WHEN dyn3 = 1 THEN 7 END
FROM (SELECT 1 AS dyn1, 1 AS dyn2, 1 AS dyn3 FROM dual);
Or, maybe you want it in an only column
SELECT CASE WHEN dyn1 = 1 THEN 7 END ||
CASE WHEN dyn2 = 1 THEN 7 END ||
CASE WHEN dyn3 = 1 THEN 7 END
from (select 1 as dyn1, 1 as dyn2, 1 as dyn3 from dual);

SQL get all IDs where Sub-IDs are exactly specified without getting other IDs where some Sub-ID's are not present

Sorry for that title, I don't know how to describe my problem in one sentence.
I have Table like this:
event | thema
-------------
1 1
1 2
2 1
2 2
2 3
3 1
3 2
3 3
3 4
4 1
4 2
4 3
What I want are the event IDs where the thema is exaclty 1, 2 and 3, not the event ID where it is only 1 and 2 or 1,2,3 and 4.
SELECT event WHERE thema=1 OR thema=2 OR thema=3
returns them all
SELECT event WHERE thema=1 AND thema=2 AND thema=3
returns nothing.
I think this should be absolutely simple, but stack is overflown...
Thanks for some help!
Group by the event and take only those having at least one thema 1 and 2 and 3 and not any other
SELECT event
from your_table
group by event
having sum(case when thema = 1 then 1 else 0 end) > 0
and sum(case when thema = 2 then 1 else 0 end) > 0
and sum(case when thema = 3 then 1 else 0 end) > 0
and sum(case when thema not in (1,2,3) then 1 else 0 end) = 0
This type of query is a "set-within-sets" query (your are looking for sets of "thema" for each event). The most general approach is aggregation using a having clause. This might be the shortest way to write the query using standard SQL:
select event
from table t
group by event
having count(distinct (case when thema in (1, 2, 3) then thema end)) = 3;
or,
first create table #themas (depending on vendor, make this a temp table or a simple table-valued variable) that contains user-specified list of thema values, then
Select event from your_table y
Where not exists
(Select * From #Themas t
where Not Exists
(Select * From your_table
where event = y.event
and thema = t.thema))
and not exists (Select * From your_table
where event = t.event
and thema not in
(Select thema From #Themas ))

SQL Server Conditional filtering

I essentially would like to execute a statement where x=1 AND a=2. If a<>2 then return results for filter x=1.
I've tried OR statement but it ignores my a=2 filter if there is a scenario where a does equal 2. Example below
select *
from dbo.test
where (x=1 and a=2)
or
x=1
For output purposes below: type = x and Id = a
Expected result when Type = 1.
Id(a) Name Person Type(x)
2 a Mike 1
7 b Jim 1
3 c Tom 1
4 d Tim 1
5 e Dave 1
Expected result when Type = 1 and Id = 2
Id(a) Name Person Type(x)
2 a Mike 1
Expected result when Type = 1 and Id <> 2 (scenario when there is no '2' in Id column)
Id(a) Name Person Type(x)
8 a Mike 1
7 b Jim 1
3 c Tom 1
4 d Tim 1
5 e Dave 1
The issue is not when Id = 2. It is returning Type = 1 when Id <> 2. Does that mean a case statement?
select *
from dbo.test
where (x=1 and a=2)
or x=1
Is the same as:
select *
from dbo.test
where x=1
AND requires both conditions be met, and OR requires one condition to be met. The value of a is irrelevant.
UPDATE:
You can get what you're after using the RANK() function in conjunction with a CASE statement:
;WITH cte AS (SELECT *,RANK() OVER(ORDER BY CASE WHEN id = 2 THEN 1 ELSE 2 END)RNK
FROM Table1
WHERE Type = 1)
SELECT *
FROM cte
WHERE RNK = 1
If id = 2 is present in the table, only that record will be returned, otherwise all records will be returned.
Demo: SQL Fiddle
I'm guessing that you want to return a single row.
insert into test(x,a,v) values (0, 0, 'No good')
insert into test(x,a,v) values (1, 0, 'OK')
insert into test(x,a,v) values (1, 2, 'Better')
You want the row that has x=1 a=2 if it is there
You want the row that has x=1 if there is none better
You want nothing if there is no x=1 row
If that's the case then it is a bit tricky. You can score the rows using a CASE statement and then pick the row that has the best value. This may give you more than one row back if there is a tie.
SELECT v
FROM test
WHERE CASE WHEN x=1 AND a=2 THEN 1000
WHEN x=1 AND a<>2 THEN 100
ELSE 0 END =
(SELECT MAX(CASE WHEN x=1 AND a=2 THEN 1000
WHEN x=1 AND a<>2 THEN 100
ELSE 0 END)
FROM test)