Suppose I have a query:
SELECT ga_channelGrouping, ga_sourceMedium, SUM(ga_sessionDuration)/SUM(ga_sessions) as avg_sessionDuration
FROM database.table
group by ga_channelGrouping, ga_sourceMedium
.
How do I select last week and this week's data from BigQuery if I have a DATE column which looks like this 2018-06-19 11:00:00 UTC.
DATE_TRUNC is a useful function to get the beginning of the week and DATE_SUB gets you to last week
DATE_TRUNC
DATE_SUB
SELECT if(date(date) >= DATE_TRUNC(current_date(), WEEK(MONDAY)),"This Week","Last Week") weekPeriod,
ga_channelGrouping,
ga_sourceMedium,
SUM(ga_sessionDuration)/SUM(ga_sessions) as avg_sessionDuration
FROM database.table
WHERE date(date) >= DATE_SUB(DATE_TRUNC(current_date(), WEEK(MONDAY)), INTERVAL 1 WEEK)
group by weekPeriod, ga_channelGrouping, ga_sourceMedium
If your week starts on a Sunday, simply change WEEK(MONDAY) to WEEK(SUNDAY)
Related
I am trying to find an easy way to exclude partial weeks from the results.
What I have so far:
WITH a AS (SELECT
FORMAT_DATE("%G-%V", created_date) as report_week
, created_date
, FORMAT_DATE('%A', created_date) AS day
, emp_id
, ROUND(SAFE_DIVIDE(SUM(working_time),3600),2) as hours
FROM `table1` a
WHERE created_date >= current_date()-10
GROUP BY 1,2,3,4,5)
SELECT
report_week
, emp_id
, hours
FROM a
WHERE day LIKE '%Monday%'
GROUP BY 1,2,3
ORDER BY report_week ASC
Input:
report_week: conversion of employee's shift date into week
created_date: date of employee's shift
day: conversion of date of employee's shift into day of week (Monday, Tuesday..)
emp_id: the employee's ID
hours: Number of worked hours by the employee
if current_date is 19 April 2022 then current_date()-10 is 9 April 2022.
Output:
The desired output is to return the number of hours worked for each employee during the full week 11 - 17 April only (it would exclude 9th, 10th, 18th and 19th of April from the results).
To obtain this, I tried to filter by having only week starting on a Monday with WHERE day LIKE '%Monday%' but in the example, it would also return the number of hours worked for each employee on 18th and 19th (since the 18th is a Monday). And if I combine this clause with AND (for example WHERE day LIKE '%Monday%' AND day LIKE '%Sunday%', it does not work at all.
Additionally, I see here another potential problem. If a Monday is a day off (like during Easter), then no employees will have hours on that Monday and the rest of the week will then not be returned.
My question: Is there an easy way to get only full weeks (Monday-Sunday) regardless the date range chosen?
Thank you in advance.
Best,
Fabien
You need to use UNNEST and create an array with a range of dates. Also, you need to use DATE_TRUNC to get the week and LAST_DAY to get the last day of the week. You can get the weeks that belong to each day in a range of dates.
You can see this example.
with sample_data as (
SELECT date FROM UNNEST(generate_timestamp_array('2022-04-09 00:00:00', '2022-04-19 00:00:00', INTERVAL 1 DAY)) as date
),
counting as(
select
DATE_ADD(DATE (date), INTERVAL 1 DAY) date
, DATE_TRUNC(DATE(date), WEEK)+1 week_start
, DATE_TRUNC(DATE(date), WEEK) +7 week_end
from sample_data
)
select b.date from (
select week_start,count(*) as ndays
from counting
group by week_start
having ndays=7
) a
join counting b on a.week_start=b.week_start
where timestamp(b.date) between timestamp(b.week_start) and timestamp(b.week_end)
I used the same range of dates like your example.
I want to extract the week as date range from a DATETIME field in bigquery.
From these docs I can extract the week as a week number like this
EXTRACT(WEEK FROM date), or get the first day as date like this DATE_TRUNC(DATE(date), WEEK)
But what if I want to get a date range, for example if the date field have the value 2021-12-23 04:30:00 and say Sunday is the first the of the week, I would like to get this result 2021-12-19 - 2021-12-25
or something similar. Is it possible?
Depending on your desired output, separate columns or single string, you can try the following:
with sample_data as (
SELECT date FROM UNNEST(generate_timestamp_array('2021-12-01 00:00:00', '2022-02-01 00:00:00', INTERVAL 1 DAY)) as date
)
select
date
, DATE_TRUNC(DATE(date), WEEK) week_start
, DATE_TRUNC(DATE(date), WEEK) +6 week_end
, LAST_DAY(DATE(date), WEEK) as alt_week_end
, concat(DATE_TRUNC(DATE(date), WEEK)," - ", DATE_TRUNC(DATE(date), WEEK) +6) week_range
from sample_data
Consider below approach
select *,
date_trunc(date(date), week) week_start,
last_day(date(date), week) week_end
from your_table
with output like
I want to query my postgresql data and group the results by week, so I'm using the following query:
select
date_trunc ('week', date_column) as week,
sum (orders) as orders_count
from database
group by week
But it uses Monday as start day of the week, while I want my weeks to be like 'Saturday -> Friday'. How can I acheive this?
Just subtract two days, and you land on saturday:
select
date_trunc('week', date_column)::date - 2 as week,
sum (orders) as orders_count
from the_table
group by week
You can just offset by two days, as follows:
select
date_trunc ('week', date_column + interval '2 days') - interval '2 days' as week,
sum (orders) as orders_count
from database
group by week
I have about 50k rows in a Postgres database that are users and when they signed up.
I am trying to understand how many users sign up for each day of the week since the start of the year, e.g.:
1238 on Monday
3487 on Tuesday
1237 on Wednesday
Example date entry: '2014-10-31 17:17:30.138579'
A plain aggregate query after extracting the weekday. You could use to_char() to get the (English by default) weekday:
SELECT to_char(created_at, 'Day'), count(*) AS ct
FROM tbl
WHERE created_at >= date_trunc('year', now())
GROUP BY 1;
If performance is important, EXTRACT() is slightly faster:
SELECT EXTRACT(ISODOW FROM created_at), count(*) AS ct
FROM tbl
WHERE created_at >= date_trunc('year', now())
GROUP BY 1;
1 .. Monday, ... , 7 .. Sunday.
You can use the EXTRACT(DOW from timestamp) to determined the day of the week. 0 is Sunday. 6 is Saturday.
Example:
SELECT EXTRACT(DOW FROM TIMESTAMP '2015-06-22 20:38:40');
Result is 1 (Monday)
I need to select recods from oracle table for the current calendar week based on a date datatype field. Currently I am doing like this:
select * from my_table where enter_date > sysdate -7
If today is Thursday, this query will select records seven days from today which infiltrates to last week on Thursday. Is there a way to select records for the current calendar week dynamically?
If your week starts on a Monday then:
select ...
from ...
where dates >= trunc(sysdate,'IW')
For alternative definitions of the first day of the week, trunc(sysdate,'W') truncates to the day of the week with which the current month began, and trunc(sysdate,'WW') truncates to the day of the week with which the current year began.
See other available truncations here: http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions255.htm#i1002084
to_char(sysdate, 'd') returns day of week in [1..7] range; so try using
select *
from my_table
where enter_date >= trunc(sysdate) - to_char(sysdate, 'd') + 1
Here is the SQLFiddel Demo
Below is the query which you can try
select Table1.*
from Table1
where dates > sysdate - TO_CHAR(SYSDATE,'D')