I want to return ISO standard week numbers (ie week 1-52/53) from a date.
I have tried using the built in function strftime, but with no success.
Can anyone suggest a way without having to write a custom C or other function.
I know this is an old question, but recently I was looking for an efficient solution for the same problem, and this is what I came up with:
SELECT
my_date,
(strftime('%j', date(my_date, '-3 days', 'weekday 4')) - 1) / 7 + 1 as iso_week
FROM my_table;
The basic idea is to calculate the ISO week number by simply performing integer division of the day of year of the Thursday of the date being looked up (my_date) by 7, giving a result between 0 and 52, and then adding 1 to it. And the subtraction by 1 just before the division is there just for the alignment of the division: Thursday of week 1, for example, can have a day of year between 1 and 7, and we want the result of the division to be 0 in all cases, so we need to subtract 1 from the day of year before dividing it by 7.
What specifically did you try?
This works for me (using built-in SQLite from Python REPL):
import sqlite3
c = sqlite3.connect(':memory:')
c.execute('''create table t (c);''')
c.execute('''insert into t values ('2012-01-01');''')
c.execute('''select c, strftime('%W',c) from t;''').fetchone()
# -> (u'2012-01-01', u'00')
OK, so I managed to answer my own question. For anyone who might need a similar solution, this is what I came up with. Please note, I do not have an IT background and my SQL is self taught.
General process
Get the Thursday of the week the date belongs too.
Get the 4th of January of the year of that Thursday.
Get the Thursday of the week the 4th January date belongs too.
Subtract Step 2 with Step 3, divide by 7 and add 1.
Translated into SQLite....
SELECT
date,
CASE CAST (strftime('%w', wknumjanfourth) AS INTEGER)
WHEN 0 THEN ((JULIANDAY(datesThur) - JULIANDAY(strftime("%s", wknumjanfourth) - 259200, 'unixepoch')) / 7) + 1
ELSE ((JULIANDAY(datesThur) - JULIANDAY(DATE(strftime("%s", wknumjanfourth) - (86400 * (strftime('%w', wknumjanfourth) - 1)), 'unixepoch'), '+3 day')) / 7) + 1
END AS weeknum
FROM
(
SELECT
date,
datesThur,
DATE(datesThur,'start of year','+3 day') AS wknumjanfourth
FROM
(SELECT
date,
CASE CAST (strftime('%w', date) AS INTEGER)
WHEN 0 THEN DATE(strftime("%s", date) - 259200, 'unixepoch')
ELSE DATE(DATE(strftime("%s", date) - (86400 * (strftime('%w', date) - 1)), 'unixepoch'), '+3 day')
END AS datesThur
FROM TEST
))
If anyone can improve this SQL, I would appreciate the feedback.
Related
I was trying to find symptoms between 2 dates. The date is obtained from a table and is not current date. The range is date +1 day to date+ 5 days. I wrote this code but it does not seem to work.
Where am I going wrong?
SELECT answer
FROM column
WHERE BETWEEN date(date,'+1 day') AND date(date, '+5 days')
--maybe like this :)
--dateadd to +5 days
SELECT x
FROM date a
WHERE a.yourDate BETWEEN a.yourDate and DateAdd(day, 5, a.yourDate)
--using GateDate();
SELECT x
FROM date a
WHERE a.yourDate BETWEEN getdate() and DateAdd(day, 5, getdate())
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
How to count days between date range with a specific day?
Example:
START_DT = January 1, 2014;
END_DT = January 31, 2014;
Day = :SampleDay
Sample Result:
Monday = 4,
Tuesday = 4,
Wednesday = 5
Please help. :|
Are you looking for something like this,
WITH t(date1, date2) AS
(
SELECT to_date('01/01/2014', 'dd/mm/yyyy'),
to_date('31/01/2014','dd/mm/yyyy')+1 -- Adding 1 to calculate the last day too.
FROM DUAL
)
SELECT count(days) day_count, day
DAY
FROM(
SELECT date1 + LEVEL -1 days,
to_char(date1 + LEVEL -1, 'FmDay') DAY, --Use `FmDay`, this will remove the Embedded spaces.
to_char(date1 + LEVEL -1, 'D') DAY#
FROM t
CONNECT BY LEVEL <= date2 - date1
)
WHERE day = 'Monday' --Filter with day, if you want to get the count for a specific day.
GROUP BY DAY, day#
ORDER BY day#;
You wont have a direct solution to this. In oracle you have this form to know what day of the week is a specific date:
to_char(to_date('01012014', 'ddmmyyyy'), 'Day')
I would recommend to you to make a store procedure with a simple algorithm which receive that three parameters and then display the information you need. Put it in a query and it is done.
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
How do I get the date of this current week's Monday. Where Monday is the first day of the week. So if I was to look up this weeks it would return the date 1/16/2012
I am using VBScript and ASP
Many thanks in advance..
Paul
Effectively, the Weekday function returns Sunday=1, Monday=2, etc. To get the Monday of the same week, you want to subtract:
Sunday (1): 6 days
Monday (2): 0 days
Tuesday(3): 1 day
...
Saturday(7): 5 days.
Or
Days to subtract = (Weekday - 2 + 7) Mod 7
So if d is a date, the Monday of the same week can be written as:
mondayofsameweek = DateAdd("d", -((Weekday(d) + 7 - 2) Mod 7), d)
VBScript has a function called WeekDay, it return 1 - 7, not sure whether 1 is Monday though, usually you can twiddle with that.
Either way get the weekday Thursday = 4? , so then you just need to take three days off your date with thae DateAdd function
In VBScript WeekDay returns the day of the week, starting with Sunday=1 (VBScript can be quirky like that). So just subtract two (Monday=2) from that value and call DateAdd.
monday = DateAdd("d",(WeekDay(Date())-2),Date())
I know the topic is a bit old, but I figured I'd share my working solution that I think is a bit more concise.
Where dDate is your current date:
dDate = DateAdd("d", -(WeekDay(dDate, vbMonday) - 1), dDate)
The second parameters of WeekDay is the day you want the week to 'start'. For me, in the US, WeekDay corresponds the default second parameter to vbSunday. Specifying vbMonday, we just get the difference (base 1) between our current weekday and Monday.
Subtract 1 and add the inverse to your current date should obtain your result.
Example:
WeekDay(2018-03-20, vbMonday) = -((2) - 1) = DateAdd("d", -1, 2018-03-20)