I want no NULL values in CASE - plsql

I'm using PL/SQL Developer and I want the column NEW_UPDATED to only display 'New in Last 30 Days' or 'Updated in Last 30 Days'
I have NULL values for records that fall outside that range and are not NEW or UPDATED and I don't want these records
CASE
WHEN live_date >= SYSDATE - 30 THEN
'New in Last 30 Days'
WHEN release_date >= SYSDATE - 30 THEN
'Updated in Last 30 Days'
END AS NEW_UPDATED

Related

Impala - Working hours between two dates in impala

I have two time stamps #starttimestamp and #endtimestamp. How to calculate number of working hours between these two
Working hours is defined below:
Mon- Thursday (9:00-17:00)
Friday (9:00-13:00)
Have to work in impala
think i found a better solution.
we will create a series of numbers using a large table. You can get a time dimension type table too. Make it doenst get truncated. I am using a large table from my db.
Use this series to generate a date range between start and end date.
date_add (t.start_date,rs.uniqueid) -- create range of dates
join (select row_number() over ( order by mycol) as uniqueid -- create range of unique ids
from largetab) rs
where end_date >=date_add (t.start_date,rs.uniqueid)
Then we will calculate total hour difference between the timestamp using unix timestamp considering date and time.
unix_timestamp(endtimestamp - starttimestamp )
Exclude non working hours like 16hours on M-T, 20hours on F, 24hours on S-S.
case when dayofweek ( dday) in (1,7) then 24
when dayofweek ( dday) =5 then 20
else 16 end as non work hours
Here is complete SQL.
select
end_date, start_date,
diff_in_hr - sum(case when dayofweek ( dday) in (1,7) then 24
when dayofweek ( dday) =5 then 20
else 16 end ) total_workhrs
from (
select (unix_timestamp(end_date)- unix_timestamp(start_date))/3600 as diff_in_hr , end_date, start_date,date_add (t.start_date,rs.uniqueid) as dDay
from tdate t
join (select row_number() over ( order by mycol) as uniqueid from largetab) rs
where end_date >=date_add (t.start_date,rs.uniqueid)
)rs2
group by 1,2,diff_in_hr

Teradata sql query - compare current day value with previous day value

I have 3 columns(CustomerId, Amount, ProcessDate) in a table (Customer).
Values are inserted daily in this table.
I want to get all the rows whose current day Amount is greater than previous day Amount.
CustomerId Amount Process_date
1 20 12/05/2021
2 30 12/05/2021
1 40 13/05/2021
2 25 13/05/2022
We have to print (1 40 13/05/2021) as 20 (previous day amount) is smaller than 40 (next day amount).
Query which I tried :-
select b.customerId, b.amount, b.process_date from customer a
join (select customerId, amount, process_date from customer where process_date = current_date ) as b
on
a.customerId = b.customerId and
a.process_date = current_date - 1 and a.amount < b.amount

How to return the previous 7 days in Teradata

SELECT
DD.DATE_DATE AS Claim_Rcv_Date
from claim claim INNER JOIN DIM_DATE DD
ON DD.DATE_DIM_CK = CLAIM.CLAIM_RCVD_DATE_DIM_CK
WHERE ???
How would I limit to the previous 7 days? Using the DD.DATE_DATE AS Claim_Rcv_Date
Assuming the date column is actually stored as a proper date type, you can use:
WHERE your_date_column BETWEEN (CURRENT_DATE - INTERVAL '7' DAY) AND CURRENT_DATE

SQL Server 2008 R2 looking for a way to get the night hours for an employee

Using SQL Server 2008 R2 we are looking for a way to select the shift hours that an employee has that are during the night which in the this case 22.00 and 6.00 +1.
Our problem becomes how to get the hours when the shift crosses midnight or how we get the overlap when a shift begins 05.30 to 22.30 and has an overlap in both the beginning and end of the shift.
Here is an example, theses are the data available in the database and the result we are looking for:
startDateTime | endDateTime | nightHours
--------------------------+---------------------------+----------------
2012-07-04 05:00:00.000 2012-07-04 23:00:00.000 2
2012-07-04 18:00:00.000 2012-07-05 05:00:00.000 7
Does anyone have an example or a few good pointer that we can use.
This may be overly complex, but it does work. We use a number of CTEs to construct useful intermediate representations:
declare #Times table (
ID int not null,
StartTime datetime not null,
EndTime datetime not null
)
insert into #Times (ID,StartTime,EndTime)
select 1,'2012-07-04T05:00:00.000','2012-07-04T23:00:00.000' union all
select 2,'2012-07-04T18:00:00.000','2012-07-05T05:00:00.000'
;With Start as (
select MIN(DATEADD(day,DATEDIFF(day,0,StartTime),0)) as StartDay from #Times
), Ends as (
select MAX(EndTime) EndTime from #Times
), Nights as (
select DATEADD(hour,-2,StartDay) as NightStart,DATEADD(hour,6,StartDay) as NightEnd from Start
union all
select DATEADD(DAY,1,NightStart),DATEADD(DAY,1,NightEnd) from Nights n
inner join Ends e on n.NightStart < e.EndTime
), Overlaps as (
select
t.ID,
CASE WHEN n.NightStart > t.StartTime THEN n.NightStart ELSE t.StartTime END as StartPeriod,
CASE WHEN n.NightEnd < t.EndTime THEN n.NightEnd ELSE t.EndTime END as EndPeriod
from
#Times t
inner join
Nights n
on
t.EndTime > n.NightStart and
t.StartTime < n.NightEnd
), Totals as (
select ID,SUM(DATEDIFF(hour,StartPeriod,EndPeriod)) as TotalHours
from Overlaps
group by ID
)
select
*
from
#Times t
inner join
Totals tot
on
t.ID = tot.ID
Result:
ID StartTime EndTime ID TotalHours
----------- ----------------------- ----------------------- ----------- -----------
1 2012-07-04 05:00:00.000 2012-07-04 23:00:00.000 1 2
2 2012-07-04 18:00:00.000 2012-07-05 05:00:00.000 2 7
You'll note that I had to add an ID column in order to get my correlation to work.
The Start CTE finds the earliest applicable midnight. The End CTE finds the last time for which we need to find overlapping nights. Then, the recursive Nights CTE computes every night between those two points in time. We then join this back to the original table (in Overlaps) to find those periods in each night which apply. Finally, in Totals, we compute how many hours each overlapping period contributed.
This should work for multi-day events. You might want to change the Totals CTE to use minutes, or apply some other rounding functions, if you need to count partial hours.
I think, the best way would be a function that takes start time and end time of the shift. Then inside the function have 2 cases: first when shift starts and ends on the same day and another case when starts on one day and finishes on the next one.
For the case when it starts and finishes on the same day do
#TotalOvernightHours=0
#AMDifference = Datediff(hh, #shiftStart, #6amOnThatDay);
if #AMDIfference > 0 than #TotalOvernightHours = #TotalOvernightHours + #AMDifference
#PMDifference Datediff(hh, #10pmOnThatDay, #ShiftEnd)
if #PMDifference > 0 than #TotalOvernightHours = #TotalOvernightHours + #PMDifference
For the case when start and finish are on different days pretend it is 2 shifts: first starts at #ShiftStart, but finishes at midnight. Second one starts at midnight, finishes at #ShiftEnd. And for every shift do apply the logic above.
In case you have shifts that a longer than 24 hours, break them up into smaller sub-shifts, where midnight is a divider. So if you have shift starting on 1 Jun 19:00 and finishing at 3 Jun 5:00 then you would end up with three sub-shifts:
1 Jun 19:00 - 1 Jun 24:00
2 Jun 00:00 - 2 Jun 24:00
3 Jun 00:00 - 3 Jun 5:00
And for every sub-shift you do calculate the overnight hours.
I'd probably would write a function that calculates overnight hours for one 24hrs period and another function that breaks the whole shift into 24hrs chunks, then feeds it into the first function.
p.s. this is not sql, only pseudo-code.
p.p.s. This would work only if you have ability to create functions. And it would get you a clean, easy-to ready code.

MySQL: Records inserted by hour, for the last 24 hours

I'm trying to list the number of records per hour inserted into a database for the last 24 hours. Each row displays the records inserted that hour, as well as how many hours ago it was.
Here's my query now:
SELECT COUNT(*), FLOOR( TIME_TO_SEC( TIMEDIFF( NOW(), time)) / 3600 )
FROM `records`
WHERE time > DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY HOUR(time)
ORDER BY time ASC
right now it returns:
28 23
62 23
14 20
1 4
28 3
19 1
That shows two rows from 23 hours ago, when it should only show one per hour.
I think it has something to do with using NOW() instead of getting the time at the start of the hour, which I'm unsure on how to get.
There must be a simpler way of doing this.
If you grouped by HOUR(time) then you should use HOUR(time) in your select expressions, and not time. For example:
SELECT HOUR(time), COUNT(*)
FROM `records`
WHERE time > DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY HOUR(time)
ORDER BY HOUR(time)
Alternatively you can group by the expression you want to return:
SELECT COUNT(*), FLOOR( TIME_TO_SEC( TIMEDIFF( NOW(), time)) / 3600 )
FROM `records`
WHERE time > DATE_SUB(NOW(), INTERVAL 24 HOUR)
GROUP BY FLOOR( TIME_TO_SEC( TIMEDIFF( NOW(), time)) / 3600 )
ORDER BY FLOOR( TIME_TO_SEC( TIMEDIFF( NOW(), time)) / 3600 )
In case you were wondering, it is safe to call NOW() multiple times in the same query like this. From the manual:
Functions that return the current date or time each are evaluated only once per query at the start of query execution. This means that multiple references to a function such as NOW() within a single query always produce the same result.

Resources