How to convert and display an Integer into YYYYMMDD format using Select query without neglecting days and leap year logic? - sql

I have a query to retrieve a set of non null records from a column x consisting of DATE format.
If count(x) = 35 then i need to display the value as 1 Month & 5 days
If 369 days then 1 year & 4 days or If 400 days then 1 year 1 month 5 days respectively
Query: In the above instance,unfortunately i am neglecting 0.25 days but How to tweak my actual requirement in such a way that i don't end up neglecting days and handle leap year logic too
How to solve this issue?

it is not clear if you need of a time's generic computing in years, months and days, based on averages of number of days of a month, etc.. or if you want an exact compute of the number of the months that pass starting froma adate.. for example if your total sum of 400 days start from 15 march, then the month is counted by 1 after, let's say, 15 days, and so the remaining days are 20.. I don't know if I explained..
In the first hypotesis, you may use the following pseudo-coded solution, that is a very approximative method..
however, if you know a start date, it is possible to compute exactly how many "bissextile" days are comprehended between your interval of days starting from your start date
let's say to have output variables Years, Months, Days .. and an input totalDaysdays assigned with your data retrieved from the db, then:
(pseudocode)
Years = trunc((totalDays / 365)
bissextileDays = trunc((totalDays / 365) / 4)
numDaysOffset = (totalDays Mod 365) + bissextileDays
Months = trunc(numDaysOffset / 30)
Days = numDaysOffset Mod 30

Actually i found something that will suit my requirement.
https://community.oracle.com/thread/2587161?start=0&tstart=0
select days,
floor(days / 365.25) years,
floor(mod(days,365.25) / (365.25 / 12)) months,
round(mod(days,365.25 / 12)) days
from periods
So this can produce expected output when number is given. This produces output as years,months and remaining days

Related

Get Number of Months and Days Between Dates

In PL/SQL I have 2 dates and I need to find out the number of months between them and the days as well. For example date 1 is 1/10/2022 and date 2 is 2/12/2022 that would be 1 month and 2 days. I'm pretty secure in obtaining the number of months, but the days number has been a thorn in my side. Sometimes it comes out correct, sometimes it comes out short and other times it comes out too far. I would imagine it is because of the different number of days in the months, but I can't prove that just yet. Any help is appreciated.
Oracle provides a months_between function to do the calculation.
That isn't a good idea as the number of days in a month varies, it's not exactly known what the decimal part of the number represents.
select months_between(date '2022-04-03', date '2022-01-01') from dual;
MONTHS_BETWEEN(DATE'2022-04-03',DATE'2022-01-01')
3.06451612903225806451612903225806451613
If you assume every month has 30 days, then comparisons over larger date ranges (years) will be out by more and more days the larger the difference gets.
However, if you combine methods, using months_between to get the months, and then assume 30 days for a month to get the days part from the remainder, it's more consistent over longer periods…
with dates as (select date '2022-01-01' as date_from, date '2022-04-03' as date_to from dual)
select months_between(date_to, date_from) ,trunc(months_between(date_to, date_from)) as months ,round(mod(months_between(date_to, date_from),1)*30) as days
from dates
MONTHS_BETWEEN(DATE_TO,DATE_FROM) MONTHS DAYS
3.06451612903225806451612903225806451613 3 2

Return the number of months between now and datetime value SQL

I apologize, I am new at SQL. I am using BigQuery. I have a field called "last_engaged_date", this field is a datetime value (2021-12-12 00:00:00 UTC). I am trying to perform a count on the number of records that were "engaged" 12 months ago, 18 months ago, and 24 months ago based on this field. At first, to make it simple for myself, I was just trying to get a count of the number of records per year, something like:
Select count(id), year(last_engaged_date) as last_engaged_year
from xyz
group by last_engaged_year
order by last_engaged_year asc
I know that there are a lot of things wrong with this query but primarily, BQ says that "Year" is not a valid function? Either way, What I really need is something like:
Date() - last_engaged_date = int(# of months)
count if <= 12 months as "12_months_count" (# of records where now - last engaged date is less than or equal to 12 months)
count if <= 18 months as "18_months_count"
count if <= 24 months as "24_months_count"
So that I have a count of how many records for each last_engaged_date period there are.
I hope this makes sense. Thank you so much for any ideas
[How to] Return the number of months between now and datetime value [in BigQuery] SQL
The simples way is just to use DATE_DIFF function as in below example
date_diff(current_date(), date(last_engaged_date), month)

How to get start & end of same week last year in DB2 using SQL?

I have a weekly report that uses these date parameters:
SELECT *
FROM TABLE
WHERE DATE_FIELD BETWEEN (CURRENT DATE - 8 DAYS) AND (CURRENT DATE - 2 DAYS)
This runs on Mondays to gather the previous week's data (Sun-Sat). What I want now is to run this for the same week of the previous year.
So for example, if the code above runs on Mon 29/06/20, it returns data from Sun 21/06/20 - Sat 27/06/20, i.e. week 26 of 2020. I want it to return data from Sun 23/06/19 - Sat 29/06/19, i.e. week 26 of 2019.
The report runs automatically so I can't just plug in the exact dates each time. I also can't just offset the date parameters to -357 and -367 days, as this gets thrown off by leap years.
I've searched for solutions but they all seem to rely on the DATEADD function, which my DB2 database doesn't recognise.
Does anyone know how I can get the result I'm looking for, please? Any advice would be appreciated! :)
The easiest way to do this is to build a calendar or dates table...(google sql calendar table)
Among the columns you'd have would be
date
year
month
quarter
dayofWeek
startOfWeek
endOfWeek
week_nbr
You can use the week() or week_iso() functions when loading the table, pay attention to the differences and pick the best fit for you.
Such a calendar table makes it easy to compare current period vs prior period.
If you assume that all years have 52 weeks, you can use date arithmetic:
SELECT *
FROM TABLE
WHERE DATE_FIELD BETWEEN (CURRENT DATE - (8 + 364) DAYS) AND (CURRENT DATE - (2 + 364) DAYS)
Because you want the week to start on a Monday, this doesn't have to take leap years into account. It is subtracting exactly 52 weeks -- and leap years do no affect weeks.
This gets more complicated if you have to deal with 52 or 53 week years.
A little bit complicated, but it should work. You may run it as is or test your own date.
SELECT
YEAR_1ST_WEEK_END + WEEKS_TO_ADD * 7 - 6 AS WEEK_START
, YEAR_1ST_WEEK_END + WEEKS_TO_ADD * 7 AS WEEK_END
FROM
(
SELECT
DATE((YEAR(D) - 1)||'-01-01')
+ (7 - DAYOFWEEK(DATE((YEAR(D) - 1)||'-01-01'))) AS YEAR_1ST_WEEK_END
, WEEK(D) - 2 AS WEEKS_TO_ADD
FROM (VALUES DATE('2020-06-29')) T(D)
);
The intermediate column YEAR_1ST_WEEK_END value is the 1-st Sat (end of week) of previous year for given date.
WEEKS_TO_ADD is a number of weeks to add to the YEAR_1ST_WEEK_END date.

Why is Redshift datediff giving different weeks when it is the same number of day difference?

I'm trying to find the number of weeks between two days. When the difference is 8 days, I should be getting 1 or 2 weeks, depending on how the function works in Redshift (rounds up or down). However, it should be consistent whichever way it chooses.
I realize that I could simply take the number of days and then divide by 7 and do either a ROUND or a CEIL, but I am simply trying to understand why DATEDIFF(weeks, date1, date2) provides either 1 or 2 when I have the two dates different by 8 days.
SELECT
DATEDIFF(weeks, '2019-03-17', '2019-03-25') AS week_difference1,
DATEDIFF(days, '2019-03-17', '2019-03-25') AS day_difference1,
DATEDIFF(weeks, '2019-03-16', '2019-03-24') AS week_difference2,
DATEDIFF(days, '2019-03-16', '2019-03-24') AS day_difference2
Result:
week_difference1 = 1
day_difference1 = 8
week_difference2 = 2
day_difference2 = 8
As with many software products from the US, the first day of the week in Redshift (at least far as DATEDIFF is concerned) is Sunday, and not the ISO standard of Monday. Therefore when calculating the number of weeks between two dates the boundary is Saturday/Sunday.
In your example, the eight days between the 16th March 2019 and 24th March 2019 crosses two week boundaries (one on 16/17 March and one on 23/24 March), so the resulting DATEDIFF value is 2 (two week boundaries crossed).
However, the eight days between the 17th March and 25th March only crosses one week boundary (23/24 March) so the resulting DATEDIFF value is 1.

SQLite - Determine average sales made for each day of week

I am trying to produce a query in SQLite where I can determine the average sales made each weekday in the year.
As an example, I'd say like to say
"The average sales for Monday are $400.50 in 2017"
I have a sales table - each row represents a sale you made. You can have multiple sales for the same day. Columns that would be of interest here:
Id, SalesTotal, DayCreated, MonthCreated, YearCreated, CreationDate, PeriodOfTheDay
Day/Month/Year are integers that represent the day/month/year of the week. DateCreated is a unix timestamp that represents the date/time it was created too (and is obviously equal to day/month/year).
PeriodOfTheDay is 0, or 1 (day, or night). You can have multiple records for a given day (typically you can have at most 2 but some people like to add all of their sales in individually, so you could have 5 or more for a day).
Where I am stuck
Because you can have two records on the same day (i.e. a day sales, and a night sales, or multiple of each) I can't just group by day of the week (i.e. group all records by Saturday).
This is because the number of sales you made does not equal the number of days you worked (i.e. I could have worked 10 saturdays, but had 30 sales, so grouping by 'saturday' would produce 30 sales since 30 records exist for saturday (some just happen to share the same day)
Furthermore, if I group by daycreated,monthcreated,yearcreated it works in the sense it produces x rows (where x is the number of days you worked) however that now means I need to return this resultset to the back end and do a row count. I'd rather do this in the query so I can take the sales and divide it by the number of days you worked.
Would anyone be able to assist?
Thanks!
UPDATE
I think I got it - I would love someone to tell me if I'm right:
SELECT COUNT(DISTINCT CAST(( julianday((datetime(CreationDate / 1000, 'unixepoch', 'localtime'))) ) / 7 AS INT))
FROM Sales
WHERE strftime('%w', datetime(CreationDate / 1000, 'unixepoch'), 'localtime') = '6'
AND YearCreated = 2017
This would produce the number for saturday, and then I'd just put this in as an inner query, dividing the sale total by this number of days.
Buddy,
You can group your query by getting the day of week and week number of day created or creation date.
In MSSQL
DATEPART(WEEK,'2017-08-14') // Will give you week 33
DATEPART(WEEKDAY,'2017-08-14') // Will give you day 2
In MYSQL
WEEK('2017-08-14') // Will give you week 33
DAYOFWEEK('2017-08-14') // Will give you day 2
See this figures..
Day of Week
1-Sunday, 2- Monday, 3-Tuesday, 4-Wednesday, 5-Thursday, 6-Saturday
Week Number
1 - 53 Weeks in a year
This will be the key so that you will have a separate Saturday's in every month.
Hope this can help in building your query.