I want to write a query sql for postgresql that can basically return me all days of a month excluding weekends.
For example (For 11/2019) :
First Week: 11/1
Second Week : 11/4 -> 11/8
Third Week : 11/11 -> 11/15
Fouth Week : 11/18 -> 11/22
Fifth Week : 11/25 -> 11/29
I can't find any postgresql request that can help, this should be automatic instead of putting each time a new date manually.
One method is:
select dt
from generate_series(date'2019-11-01', date'2019-11-30', interval '1' day) as t(dt)
where extract(dow from dt) between 1 and 5
generate_series() produces a list of all days in the month, then the where clause filters on week days only.
Related
I google data studio, I have a field called week that contains the week number the value is string 'Week 2' for example. How can I extract the last day of the week based on the week number. In this case I want to get 2023-01-14 which is the last day of week 2?
enter image description here
Have you tried the last_day function?
I would build from the using the date using last_day, because from the week number it would require a bit more code.
SELECT *,
LAST_DAY(today, WEEK) AS last_day_of_week,
EXTRACT(WEEK FROM today) AS week_number
FROM (SELECT CURRENT_DATE() AS today)
But if you need to go with just the week number, I recommend taking a look into this other question How to create date based on year, week number and day in bigquery .
The following code works:
DATEtime_ADD(DATEtime_TRUNC(DATEtime_ADD(DATEtime_TRUNC(date, WEEK), INTERVAL (week-1) * 1 DAY), WEEK), INTERVAL 6 DAY)
i am trying to Extract day from a quarter from a date in BigQuery.
Any help needed .
For example :
Date : 11-Feb-2022
Output : 42
Using UNIX_DATE, you can calculate days since first day of the quarter.
SELECT UNIX_DATE(PARSE_DATE('%d-%b-%Y', '11-Feb-2022')) -
UNIX_DATE(DATE_TRUNC(PARSE_DATE('%d-%b-%Y', '11-Feb-2022'), QUARTER)) + 1 AS elapsed_days
I have two event tables with timestamped data: Registered, Signed_In.
Both have rows such as: original_timestamp, user_id
I am trying to find out users who haven't signed in within 30 days after registering. I have used the following query but I cannot add a WHERE clause to it.
I tried a query but I am getting hourly difference, whereas I wanted days difference which is unsupported in BigQuery.
SELECT Signed_In.user_id, TIMESTAMP_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, HOUR) AS days_difference
FROM `test_db.Signed_In` signed_in
JOIN `test_db.Registered` registered
ON Signed_In.user_id = Registered.user_id
GROUP BY 1,2
ORDER BY 2 DESC
WHERE days_difference > '30'
I am getting two columns: user_id, days_difference but the days_difference shows hours and my WHERE clause is rejected when I use it.
You can try this below code-
Note: Using Ordinal Position for GROUP BY and ORDER BY is not a good practice. Its always safe and standard to use the column names directly.
SELECT Signed_In.user_id,
TIMESTAMP_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, HOUR) AS days_difference
FROM `test_db.Signed_In` signed_in
JOIN `test_db.Registered` registered
ON Signed_In.user_id = Registered.user_id
WHERE DATE_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, Day) > '30'
GROUP BY 1,2
ORDER BY 2 DESC
Just replace HOUR to DAY in your query:
SELECT Signed_In.user_id, TIMESTAMP_DIFF(Registered.original_timestamp, Signed_In.original_timestamp, DAY) AS days_difference
Correct values are:
MICROSECOND
MILLISECOND
SECOND
MINUTE
HOUR
DAYOFWEEK
DAY
DAYOFYEAR
WEEK: Returns the week number of the date in the range [0, 53]. Weeks begin with Sunday, and dates prior to the first Sunday of the year are in week 0.
WEEK(<WEEKDAY>): Returns the week number of timestamp_expression in the range [0, 53]. Weeks begin on WEEKDAY. datetimes prior to the first WEEKDAY of the year are in week 0. Valid values for WEEKDAY are SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, and SATURDAY.
ISOWEEK: Returns the ISO 8601 week number of the datetime_expression. ISOWEEKs begin on Monday. Return values are in the range [1, 53]. The first ISOWEEK of each ISO year begins on the Monday before the first Thursday of the Gregorian calendar year.
MONTH
QUARTER
YEAR
ISOYEAR: Returns the ISO 8601 week-numbering year, which is the Gregorian calendar year containing the Thursday of the week to which date_expression belongs.
DATE
DATETIME
TIME
I would like to get data of the last four weeks. Now, I usually run the query on a Tuesday, therefore I have this code:
AND datatime between dateadd(day,-30,getdate()) and dateadd(day,-2,getdate())
I would like to run the query whenever I want (not just on Tuesday), but obtaining also the data from the same period (last four weeks from Monday to Sunday).
I have tried to do the following
AND datatime between dateadd(week,-4,getdate()) and dateadd(week,-1,getdate())
but it does not work, as the data obtained is not from the previous weeks (Monday to Sunday) but from the 7 days before the date in which I run it.
Any ideas on how to get the data, using that structure, so that I get data from the 4 previous weeks (Monday to Sunday) no matter when I run the query?
P.S I am using DBeaver.
Thank you.
If you want all data from the first monday in the last 4 weeks to today, you can use this :
AND datatime >= DATE_ADD(
DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY),
INTERVAL - 4 WEEK)
But, if you want all the data from the first monday of the last 4 weeks to the last sunday, you can use this :
AND datatime >= DATE_ADD(
DATE_ADD(CURDATE(), INTERVAL - WEEKDAY(CURDATE()) DAY),
INTERVAL - 4 WEEK)
AND datatime < DATE_SUB(
DATE(NOW()), INTERVAL DAYOFWEEK(NOW())-2 DAY)
What's happening :
You can find Date and Time Functions Here. In this query, we are using:
DATE_ADD(start, Interval) : Add time values (Interval) to a date value (start),
DATE_SUB(end, Interval) : Subtract a time value (Interval) from a date (end),
CURDATE() : Returns the current date,
WEEKDAY(date) : Returns the weekday index for date (0 = Monday, 1 = Tuesday, … 6 = Sunday),
DAYOFWEEK(date) : Returns the weekday index for date (1 = Sunday, 2 = Monday, …, 7 = Saturday)
So :
DATE_ADD(
DATE_ADD(----------------------------------------------------------
CURDATE(), |
INTERVAL - WEEKDAY(CURDATE()) DAY //<== Return Today Index |-> Will Return the date of this week's monday : (25-01-2018 - 3 DAY) = 22-01-2018
(WEEKDAY(25-01-2018) = 3)|
),-----------------------------------------------------------------
INTERVAL - 4 WEEK //<== Will go 4 weeks back and start from monday
)
A working case Scenario.
I have a date in sql which will always fall on a Monday and I'm subtracting 13 weeks to get a weekly report. I am trying to get the same 13 week report but for last year's figures as well.
At the moment, I'm using the following:
calendar_date >= TRUNC(sysdate) - 91
which is working fine.
I need the same for last year.
However, when I split this into calendar weeks, there will also be a partially complete week as it will include 1 or 2 days from the previous week. I need only whole weeks.
e.g. the dates that will be returned for last year will be 14-Feb-2015 to 16-May-2015. I need it to start on the Monday and be 16-Feb-2015. This will change each week as I am only interested in complete weeks...
I would do this:
Get the date by substracting 91 days as you're already doing.
Get the number of the day of the week with TO_CHAR(DATE,'d')
Add the number of days until the next monday to the date.
Something like this:
SELECT TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/YYYY')-91 + MOD(7 - TO_NUMBER(TO_CHAR(TO_DATE(TO_DATE('16/05/2015','DD/MM/YYYY'),'DD/MM/RRRR')-91,'d'))+1,7) d
FROM dual
next_day - returns date of first weekday named by char.
with dates as (select to_date('16/05/2015','DD/MM/YYYY') d from dual)
select
trunc(next_day( trunc(d-91) - interval '1' second,'MONDAY'))
from dates;
I want to get next monday from calculated date. In situation when calculated date is monday i have to move back to previous week ( -1 second).