Teradata min between two dates - teradata

Hi i am relatively new to teradata. I have a row with 2 dates. I need to get the min between these tow dates and show it as third date. The dates are in YYYYMMDD format. Here are all the posiblities
example table
col1--date1--date2
123--20140802--20140619
124--20140802--0
124--0--20140802
125--0--0
I need my result set to be
col1--date1--date2--min_date
123--20140802--20140619--6/19/2014
124--20140802--0--8/2/2014(non zero will be min_date)
124--0--20140802--8/2/2014(non zero will be min_date)
125--0--0--?
This is what i could come up with
select col1, date1, date2,
case
when date1 <> 0 and date2 = 0 then cast((date1 - 19000000) as date)
when date1 = 0 and date2 <> 0 then cast((date2 - 19000000) as date)
when date1 = 0 and date2 = 0 then cast(null as date)
when date1 > date2
then
cast((date2 - 19000000) as date)
else
cast((date1 - 19000000) as date)
end as min_date
This does give me result, but query is slow. I wanted to know if there was better and efficient way of doing this, please let me know. I also need to show the min_date in another format as below
col1--date1--date2--min_date--min_month
123--20140802--20140619--6/19/2014--Jun, 2014
124--20140802--0--8/2/2014--Aug, 2014
124--0--20140802--8/2/2014--Aug, 2014
125--0--0--null--null
For min_month i know i can use this if i know which of the dates to use
cast(cast((date2 or date2 - 19000000) as date format 'MMM') as Char(3))
|| ', ' ||
cast(cast((date2 or date2 - 19000000) as date format 'YYYY') as Char(4))
Any help is highly appreciated.
Thanks in advance..

The CASE can be simplified to
CAST(CASE
WHEN date1 = 0 AND date2 = 0 THEN NULL
WHEN date1 > date2 THEN date1
ELSE date2
END - 19000000 AS DATE) AS min_date
Formatting the date:
min_date (FORMAT 'mmm,byyyy') (CHAR(9))

Related

Get the MAX(value) using fiscal type years ie; 2016/2017, etc

My calendar year runs from 07-01-(of one year) to 06-30-(of the next year).
My SQLITE DB has a Timestamp column and it's data type is datetime and stores the timestamp as 2023-09-01 00:00:00.
What I'm trying to do is get the MAX date of the latest snowfall. For example, with my seasonal years beginning July-01 (earliest) and ending June 30 (latest), I want to find only the latest (MAX) date snowfall was recorded, regardless of the year, based on the month.
Say if out of five years (2017 to 2022) worth of data in the database and it snowed Mar 15, 2020. And there was no date greater than than this one in any year, then this would be the latest date regardless which year it fell.
I've been trying many variations of the below query. This query says it runs with no mistakes and returns "null" values. I'm using SQLITE DB Browser to write and test the query.
SELECT Timestamp, MAX(strftime('%m-%d-%Y', Timestamp)) AS lastDate,
snowDepth AS lastDepth FROM DiaryData
WHERE lastDepth <> 0 BETWEEN strftime('%Y-%m-%d', Timestamp,'start of year', '+7 months')
AND strftime('%Y-%m-%d', Timestamp, 'start of year', '+1 year', '+7 months', '- 1 day')
ORDER BY lastDate LIMIT 1
and this is what's in my test database:
Timestamp snowFalling snowLaying snowDepth
2021-11-10 00:00:00 0 0 7.2
2022-09-15 00:00:00 0 0 9.5
2022-12-01 00:00:00 1 0 2.15
2022-10-13 00:00:00 1 0 0.0
2022-05-19 00:00:00 0 0 8.82
2023-01-11 00:00:00 0 0 3.77
If it's running properly I should expect:
Timestamp
lastDate
lastDepth
2022-05-19 00:00:00
05-19-2022
8.82
What am I missing or is this not possible in SQLITE? Any help would be appreciative.
Use aggregation by fiscal year utilizing SQLite's feature of bare columns:
SELECT Timestamp,
strftime('%m-%d-%Y', MAX(Timestamp)) AS lastDate,
snowDepth AS lastDepth
FROM DiaryData
WHERE snowDepth <> 0
GROUP BY strftime('%Y', Timestamp, '+6 months');
See the demo.
I'd get season for each record first, snowfall date relative to record's season start date after this, and largest snowfall date relative to record's season start date finally:
with
data as (
select
*
, case
when cast(strftime('%m', "Timestamp") as int) <= 7
then strftime('%Y-%m-%d', "Timestamp", 'start of year', '-1 year', '+6 months')
else strftime('%Y-%m-%d', "Timestamp", 'start of year', '+6 months')
end as "Season start date"
from DiaryData
where 1==1
and "snowDepth" <> 0.0
)
, data2 as (
select
*
, julianday("Timestamp") - julianday("Season start date")
as "Showfall date relative to season start date"
from data
)
, data3 as (
select
"Timestamp"
, "snowFalling"
, "snowLaying"
, "snowDepth"
from data2
group by null
having max("Showfall date relative to season start date")
)
select
*
from data3
demo
You can use the ROW_NUMBER window function to address this problem, yet need to apply a subtle tweak. In order to account for fiscal years, you can partition on the year for timestamps slided 6 months further. In this way, ranges like [2021-01-01, 2021-12-31] will instead be slided to [2021-06-01, 2022-05-31].
WITH cte AS (
SELECT *, ROW_NUMBER() OVER(
PARTITION BY STRFTIME('%Y', DATE(Timestamp_, '+6 months'))
ORDER BY Timestamp_ DESC ) AS rn
FROM tab
)
SELECT Timestamp_,
STRFTIME('%d-%m-%Y', Timestamp_) AS lastDate,
snowDepth AS lastDepth
FROM cte
WHERE rn = 1
Check the demo here.

How to calculate previous month data on starting of next month in Teradata

I am using condition below to show data for current month only/previous month(if its new month started).
let's say today is 3rd june so it should only give 1st an 2nd data,if its 10 it should give data from 1 to 9th,similarly it should be like this until month end but when there will be 1st of next month it should give data from previous month. the conditions I am using are giving blank data on every 1st. . Here is the condition I am using:
where Datestarted between CURRENT_DATE - EXTRACT( DAY FROM CURRENT_DATE) + 1
AND
ADD_MONTHS(( CURRENT_DATE - EXTRACT (DAY FROM CURRENT_DATE) + 1), 1) - 1
You probably need to base your calculation on yesterday, not today:
where Datestarted between (CURRENT_DATE-1) - EXTRACT( DAY FROM CURRENT_DATE-1) + 1
AND
CURRENT_DATE-1
Do you maybe mean previous month to date?
Try this:
select
calendar_date
from
sys_calendar.calendar
where
calendar_date between cast((ADD_MONTHS(CURRENT_DATE,-1)/100*100)+1 as DATE) and
add_months(current_date,-1)-1
EDIT: Based on your comments, let's try this:
SELECT
calendar_date
FROM
sys_calendar.CALENDAR
WHERE
(EXTRACT(DAY FROM CURRENT_DATE) = 1 --previous month
AND
Calendar_Date BETWEEN CAST((ADD_MONTHS(CURRENT_DATE, - 1)/100 * 100) + 1 AS DATE)
AND CURRENT_DATE - EXTRACT(DAY FROM CURRENT_DATE))
OR--current mtd
(
Calendar_Date BETWEEN CAST((CURRENT_DATE / 100 * 100) + 1 AS DATE)
AND CURRENT_DATE - 1
)
ORDER BY calendar_date

Get DateTime corresponding to last Thu or Fri or Mon etc in SQL Server 2012

I have a certain DATETIME value, and I would like to get the DATETIME value for a given weekday 'n' (where n is an integer from 1 thru to 7) that is just before the given date.
Question: How would I do this given a value for currentDate and a value for lastWeekDay?
For example, if given date is 06/15/2015 in mm/dd/yyyy format, then what is the date for a weekday of 6 that came just before 06/15/2015. In this example, given date is on Monday and we want the date for last Friday (i.e. weekday =6).
declare #currentDate datetime, #lastWeekDay int;
set #currentDate = getdate();
set #lastWeekDay = 6;--this could be any value from 1 thru to 7
select #currentDate as CurrentDate, '' as LastWeekDayDate --i need to get this date
UPDATE 1
In addition to the excellent answer by Anon, I also found an alternate way of doing it, which is as given below.
DECLARE #currentWeekDay INT;
SET #currentWeekDay = DATEPART(WEEKDAY, #currentDate);
--Case 1: when current date week day > lastWeekDay then subtract
-- the difference between the two weekdays
--Case 2: when current date week day <= lastWeekDay then go back 7 days from
-- current date, and then add (lastWeekDay - currentWeekDay)
SELECT
#currentDate AS CurrentDate,
CASE
WHEN #currentWeekDay > #lastWeekDay THEN DATEADD(DAY, -1 * ABS(CAST(#lastWeekDay AS INT) - CAST(#currentWeekDay AS INT)), #currentDate)
ELSE DATEADD(DAY, #lastWeekDay - DATEPART(WEEKDAY, DATEADD(DAY, -7, #currentDate)), DATEADD(DAY, -7, #currentDate))
END AS LastWeekDayDate;
Calculate how many days have passed since a fixed date, modulo 7, and subtract that from the input date. The magic number '5' is because Date Zero (1900-01-01) is a Monday. Shifting that forward 5 days makes the #lastWeekDay range [1..7] map to the range of weekdays [Sunday..Saturday].
SELECT DATEADD(day,-DATEDIFF(day,5+#lastWeekDay,#currentDate)%7,#currentDate)
I avoid the DATEPART(weekday,[...]) function because of SET DATEFIRST

T-SQL - Determine number of specific days between 2 dates based on sales

The Problem: Given a day of the week (1, 2, 3, 4, 5, 6, 7), a starting date and an ending date, compute the number of times the given day of the week appears between the starting and ending dates not inclusive of a date for which there were no sales.
Context:
Table "Ticket" has the following structure and sample content:
i_ticket_id c_items_total dt_create_time dt_close_time
----------------------------------------------------------------------------
1 8.50 '10/1/2012 10:23:00' '10/1/2012 11:05:05'
2 10.50 '10/1/2012 11:00:00' '10/1/2012 11:45:05'
3 8.50 '10/2/2012 08:00:00' '10/2/2012 09:25:05'
4 8.50 '10/4/2012 08:00:00' '10/4/2012 09:25:05'
5 7.50 '10/5/2012 13:22:23' '10/5/2012 14:33:27'
.
.
233 6.75 '10/31/2012 23:20:00' '10/31/2012 23:55:39'
Details
There may or may not be any tickets for one or more days during a month. (i.e. the place was closed that/those day/s)
Days in which the business is closed are not regular. There is no predictable pattern.
Based on Get number of weekdays (Sundays, Mondays, Tuesdays) between two dates SQL,
I have derived a query which returns the number of times a given day of the week occurs between the start date and the end date:
DECLARE #dtStart DATETIME = '10/1/2013 04:00:00'
DECLARE #dtEnd DATETIME = '11/1/2013 03:59:00'
DECLARE #day_number INTEGER = 1
DECLARE #numdays INTEGER
SET #numdays = (SELECT 1 + DATEDIFF(wk, #dtStart, #dtEnd)-
CASE WHEN DATEPART(weekday, #dtStart) #day_number THEN 1 ELSE 0 END -
CASE WHEN DATEPART(weekday, #dtEnd) <= #day_number THEN 1 ELSE 0 END)
Now I just need to filter this so that any zero-dollar days are not included in the count. Any help you can provide to add this filter based on the contents of the tickets table is greatly appreciated!
If I understand correctly, you can use a calendar table to count the number of days where the day of week is n and between the start and end and is a date that has ticket sales, which I guess is when the date exists in tickets and has the sum(c_items_total) > 0
WITH cal AS
(
SELECT cast('2012-01-01' AS DATE) dt, datepart(weekday, '2012-01-01') dow
UNION ALL
SELECT dateadd(day, 1, dt), datepart(weekday, dateadd(day, 1, dt))
FROM cal
WHERE dt < getdate()
)
SELECT COUNT(1)
FROM cal
WHERE dow = 5
AND dt BETWEEN '2012-04-01' AND '2012-12-31'
AND EXISTS (
SELECT 1
FROM tickets
WHERE cast(dt_create_time AS DATE) = dt
GROUP BY cast(dt_create_time AS DATE)
HAVING sum(c_items_total) > 0
)
OPTION (MAXRECURSION 0)
SQLFiddle

Add numbers of day to Date SqLite

I need add +1 Day, to a selectec Date, in Slq the sintax is: SELECT DATEADD(day,+1, period.DateEnd) and it works, but in sqLite es different.
I try with this, but it doesn't work, for example, the DateEnd = '31/12/2012', I need add 1 day to that date, te resulset should be: DateEnd = '01/01/2013'
SELECT date('period2.DateEnd', '+1 day') as date
FROM Period as period2
WHERE period2.c_Pk_CodPeriod = '1012'
Currently you've got period2.DateEnd as a string. I suspect you want:
SELECT date(period2.DateEnd, '+1 day') as date
FROM Period as period2
WHERE period2.c_Pk_CodPeriod = '1012'

Resources