Create view with multiple case without fonction - sql

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.

Related

How to return matching column value where only all subqueries are true

I'd like to adjust the below SQL statement so that it only returns the PART_ID where all SELECT PART_ID FROM FABRICATION... conditions are met.
Currently the below statement would return part_id's 1 & 2, when the intent is to only return 1.
Thanks for any advice you can offer.
SELECT *
FROM Part
WHERE Section = 'C6x1_5/8x1/4'
AND Length BETWEEN 41.99 AND 42.01
AND Part.Part_ID IN (SELECT Part_ID FROM Fabrication
WHERE Type LIKE 'HOLE'
AND Face = 1
AND Side = 3
AND Location BETWEEN 2.99 AND 3.01
AND Offset = 2
AND Parameter_1 = 0.5625)
AND Part.Part_ID IN (SELECT Part_ID FROM Fabrication
WHERE Type LIKE 'HOLE'
AND Face = 1
AND Side = 3
AND Location BETWEEN 5.99 AND 6.01
AND Offset = 2
AND Parameter_1 = 0.5625)
Fabrication Table:
PART_ID
TYPE
FACE
SIDE
LOCATION
OFFSET
PARAMETER_1
PARAMETER_2
PARAMETER_3
1
HOLE
1
3
6
2
0.5625
0
0
1
HOLE
1
3
3
2
0.5625
0
0
2
HOLE
1
3
6
2
0.5625
0
0
2
HOLE
1
3
3
2
0.5625
0
0
2
HOLE
1
3
9
2
0.5625
0
0
3
HOLE
1
3
3
2
0.5625
0
0
You can use aggregation and HAVING to validate that there there is exactly one match for each condition and no others:
SELECT *
FROM Part
WHERE Section = 'C6x1_5/8x1/4' AND
Length BETWEEN 41.99 AND 42.01
Part.Part_ID IN (SELECT f.Part_ID
FROM Fabrication f
GROUP BY f.Part_ID
HAVING SUM(CASE WHEN f.Type = 'HOLE' AND f.Face = 1 AND f.Side = 3 AND f.Offset = 2 AND f.Parameter_1 = 0.5625 THEN 1 ELSE 0 END) = COUNT(*) AND
SUM(CASE WHEN Location BETWEEN 2.99 AND 3.01 THEN 1 ELSE 0 END) = 1 AND
SUM(CASE WHEN Location BETWEEN 5.99 AND 6.01 THEN 1 ELSE 0 END) = 1
);
It looks like the only variance in your two queries is Location, for which you want to ensure the number of Fabrication rows meet your criteria and do not have any additional rows outside of your criteria.
One option you can try uses conditional aggregation:
select *
from Part
where Section = 'C6x1_5/8x1/4'
and Length between 41.99 and 42.01
and Part.Part_ID in (
select PART_ID
from Fabrication
where
TYPE = 'HOLE'
and FACE = 1
and SIDE = 3
and offset = 2
and PARAMETER_1 = 0.5625
group by PART_ID
having Count(*)=Sum(case when LOCATION between 2.99 and 3.01 then 1 end) + Sum(case when LOCATION between 5.99 and 6.01 then 1 end)
)

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

return value when count equals variable in sql server

I have a table to update with other table data. For this I created a trigger. Inside trigger, I must check how many active occurrences of each id. If this number of occurrences is same number than a variable value then return 1 (true) otherwise 0 (false).
I get the variable
DECLARE #num_gerencias numeric(2, 0)
SELECT #num_gerencias = (SELECT COUNT(id_gerencia) FROM FR_GERENCIES)
select #num_gerencias
This works ok... returns 5
Then, I make a count of occurrences of the l_activo variable in other table (variable is a bit):
SELECT id_operacio, SUM(CASE WHEN l_activo = 1 THEN 1 ELSE 0 END)
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio
This query also works nice, returns:
2958 5
2959 0
2960 5
2961 3
2962 5
2963 5
2964 2
2965 4
2966 5
2967 5
All perfect... now i must get same list, but if sum equals to #num_gerencias, then put 1 and 0 otherwise.
Expected result table
2958 1
2959 0
2960 1
2961 0
2962 1
2963 1
2964 0
2965 0
2966 1
2967 1
I've tried with CASE
SELECT DISTINCT id_operacio, CASE WHEN
(
SELECT SUM(CASE WHEN l_activo = 1 THEN 1 ELSE 0 END)
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio
) = #num_gerencias THEN 1 ELSE 0 END
but I'm getting error:
Mens . 512 , Level 16 , State 1, Line 6
The subquery returned more than one value , which is not correct when it goes below = , ! = , <, < = ,>, > = Or when used as an expression .
I also tried with an IF (i guess this option is totally wrong for this case... but I've tried)
SELECT DISTINCT id_operacio,
IF #num_gerencias = (SELECT SUM(CASE WHEN l_activo = 1 THEN 1 ELSE 0 END)
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio)
1
ELSE 0
FROM FR_GERENCIES_OPERACIONS
But I have syntax errors...
Any idea how can i reach expected result table?
You were nearly there, however your grouping and selection must occur outside of your case statement:
SELECT DISTINCT
id_operacio
,CASE
WHEN SUM(CAST(l_activo AS INTEGER)) = #num_gerencias THEN 1
ELSE 0
END
FROM FR_GERENCIES_OPERACIONS o
GROUP BY o.id_operacio

Values of columns in first table refer to column names in second table. How to pull the values from second table?

First post, have been searching extensively for a month for an answer to this and figured I would just ask the experts.
I have populated a table with patient accounts that have received services at a hospital. I am pulling columns listing the performing physician on each of their procedures. The values of those columns are sequence numbers that point me to a set of columns in a second table. The columns in the second table actually contain the physician identifiers I need.
Example:
TABLE 1
Account: Phys_Proc1 Phys_Proc2 PhysProc3 PhysProc4 PhysProc5`
Patient1 2 5 1 4 5
Patient2 1 3 3 4 0
Patient3 2 0 0 0 0
TABLE 2
Account: Physician1 Physician2 Physician3 Physician4 Physician5
Patient1 500123 500456 500789 600123 600456
Patient2 400321 500700 300876 456789 987654
Patient3 300500 800700 0 0 0
I need up update the records in TABLE 1 with the values from TABLE 2 where the value in TABLE 1 refers to the column name from TABLE 2.
EXAMPLE
Patient1 had procedure1 performed by '500456' (Phys_Proc1's value is "2" which refers to the Physician2 field in TABLE 2.)
Any help would be greatly appreciated. Even a hint at this point would give me a direction to look in. Pointing me toward a specific function name to search is better than what I have now (nothing.) I tried an extensive CASE statement but it didn't pull the values for each patient account and pulled the values from TABLE 2 for the first account and applied it to all patient records.
UPDATE Table2
SET
Physc_Proc1 =
CASE WHEN Phys_Proc1 = 1 Then Table2.Physician1
CASE WHEN Phys_Proc1 = 2 Then Table2.Physician2
CASE WHEN Phys_Proc1 = 3 Then Table2.Physician3
CASE WHEN Phys_Proc1 = 4 Then Table2.Physician4
CASE WHEN Phys_Proc1 = 5 Then Table2.Physician5
ELSE NULL
END,
Physc_Proc2 =
CASE WHEN Phys_Proc2 = 1 Then Table2.Physician1
CASE WHEN Phys_Proc2 = 2 Then Table2.Physician2
CASE WHEN Phys_Proc2 = 3 Then Table2.Physician3
CASE WHEN Phys_Proc2 = 4 Then Table2.Physician4
CASE WHEN Phys_Proc2 = 5 Then Table2.Physician5
ELSE NULL
END,
PhyscProc3 =
CASE WHEN PhysProc3 = 1 Then Table2.Physician1
CASE WHEN PhysProc3 = 2 Then Table2.Physician2
CASE WHEN PhysProc3 = 3 Then Table2.Physician3
CASE WHEN PhysProc3 = 4 Then Table2.Physician4
CASE WHEN PhysProc3 = 5 Then Table2.Physician5
ELSE NULL
END,
PhyscProc4 =
CASE WHEN PhysProc4 = 1 Then Table2.Physician1
CASE WHEN PhysProc4 = 2 Then Table2.Physician2
CASE WHEN PhysProc4 = 3 Then Table2.Physician3
CASE WHEN PhysProc4 = 4 Then Table2.Physician4
CASE WHEN PhysProc4 = 5 Then Table2.Physician5
ELSE NULL
END,
PhyscProc5 =
CASE WHEN PhysProc5 = 1 Then Table2.Physician1
CASE WHEN PhysProc5 = 2 Then Table2.Physician2
CASE WHEN PhysProc5 = 3 Then Table2.Physician3
CASE WHEN PhysProc5 = 4 Then Table2.Physician4
CASE WHEN PhysProc5 = 5 Then Table2.Physician5
ELSE NULL
END
FROM Table2
INNER JOIN Table1
ON Table2.Account = Table1.Account
Note: I haven't tried this for syntax. I hope this gives you an idea on how to proceed further.

Remove rows from SQL when "CASE ELSE" happens

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