sql fiddle: http://sqlfiddle.com/#!4/a717b/1
Here is my Code:
select key, status, dat, sysdat, (case when key = 1 and type = 'Car' status = 'F' then round( sysdat-dat,2) else 0 end ) as Days, (case when key = 1 and type ='Bus' and Status = 'F' then round( sysdat-dat,2) else 0 end) as Days from ABC
Expected Output:
So I want to calculate days between the 'dat' column and current date for the following conditions.
1) For every key, The sequence is always car first, bus second. which means that for every key, only when the status of the car is true we check for the bus.
2) If the Status OF 'CAR' IS 'T' then I don't want to calculate the days
3) If the Status of 'Car' IS 'F' then I want to calculate the days only for the 'Car' and not for 'Bus' because it is always 'car' first 'bus' second
4) If the Status of 'Bus' is 'F' and Status of 'Car' is 'T' then I calculate the days because it matches the condition, 'Car' first and 'Bus' second.
With 2 vehicles
If you always have a car and a bus, and only a car and a bus of the same key, you could self-join the table, and check if either the vehicle a
(which you're querying) is Car with status F, or if the related verhicle, b
, is a car with status T. In either case you're gonna get a date, and in any other case you don't. That covers your example, and also implies that if car and bus would both be T, the date would still be shown next to the bus only.
select a.key, a.type, a.status, a.dat,
case when
(a.type = 'car' and a.Status = 'F') or -- a is a car and is F
(b.type = 'car' and b.Status = 'T') -- a is related to a car (b), which is T
then
trunc(sysdate) - a.dat
end as DAYS
from
ABC a
join ABC b on b.key = a.key and b.type <> a.type
order by
-- Sort the query by key first, then type.
a.key,
decode(a.type, 'car', 1, 2)
The query above: http://sqlfiddle.com/#!4/a717b/5/0
With N vehicles
If you have more vehicles, a different approach can be better, especially when the number of vehicles is high, or not fixed.
The query below has a list of all the vehicles and their sort order. This is an inline view now, but you could use a separate lookup table for that. A lookup table is even more flexible, because you can just add vehicle types or change their sort order.
Anyway, that lookup table/view can be joined on your main table to have a sort order for each of your record.
You can then make a ranking using window function like rank
or dense_rank
to introduce a numbering based on that sort order ("falsenumber"), and the fact that status is 'F'. After that, it's easy to put the date on the first row that is F (falsenumber = 1).
with
VW_TYPES as
-- This could be a lookup table as well, instead of this hard-codeslist of unions.
( select 'car' as type, 1 as sortorder from dual union all
select 'bus' as type, 2 as sortorder from dual union all
select 'train' as type, 3 as sortorder from dual union all
select 'airplane' as type, 4 as sortorder from dual union all
select 'rocket' as type, 5 as sortorder from dual),
VW_TYPESTATUS as
( select
a.*,
t.sortorder,
dense_rank() over (partition by key order by case when a.status = 'F' then t.sortorder end) as falsenumber
from
ABC a
join VW_TYPES t on t.type = a.type)
select
ts.key, ts.type, ts.status, ts.dat,
case when ts.falsenumber= 1 then
trunc(sysdate) - ts.dat
end as DAYS
from
VW_TYPESTATUS ts
order by
ts.key, ts.sortorder
The query above: http://sqlfiddle.com/#!4/71f52/8/0
Vehicle types in a separate table: http://sqlfiddle.com/#!4/f055d/1/0
Do note that oracle is case sensitive. 'car' and 'Car' and 'CAR' are not the same thing. Use lower(type) = 'car'
if you want to allow type
to contain the vehicle type with any casing. Do note that that's bad for using indexes, although I think the impact isn't that bad, since you only got a couple of rows per key.
Alternatively (arguably better), you could introduce a numeric VehicleTypeId in the new types table, and use that id in the ABC table, instead of the string 'Car'.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.