Postgresql Week number same for Jan and Dec dates - postgresql

In PostgreSQL, I am trying to convert timestamps into week numbers using the query below.
select user_id,
time_stamp,
date(time_stamp),
EXTRACT(YEAR FROM time_stamp) as Year,
EXTRACT(MONTH FROM time_stamp) as Month,
EXTRACT(WEEK FROM time_stamp) as Week
from user_engagement
user_id | time_stamp | date | year | month | week
---------+---------------------+------------+------+-------+------
6282 | 2013-01-01 14:29:35 | 2013-01-01 | 2013 | 1 | 1
6282 | 2013-01-02 14:29:35 | 2013-01-02 | 2013 | 1 | 1
6282 | 2013-12-30 14:29:35 | 2013-12-30 | 2013 | 12 | 1
6282 | 2013-12-31 14:29:35 | 2013-12-31 | 2013 | 12 | 1
I am surprised to see that the week numbers of the dates in Jan and Dec of the year 2013 are the same. Could someone explain the logic here?

I think the documentation explains this pretty well:
week
The number of the ISO 8601 week-numbering week of the year. By
definition, ISO weeks start on Mondays and the first week of a year
contains January 4 of that year. In other words, the first Thursday of
a year is in week 1 of that year.
In the ISO week-numbering system, it is possible for early-January
dates to be part of the 52nd or 53rd week of the previous year, and
for late-December dates to be part of the first week of the next year.
For example, 2005-01-01 is part of the 53rd week of year 2004, and
2006-01-01 is part of the 52nd week of year 2005, while 2012-12-31 is
part of the first week of 2013. It's recommended to use the isoyear
field together with week to get consistent results.

Related

Check opening hours in different timezones

My Specs:
Postgres 9.6.6, latest Ubuntu LTS
Server Timezone is GMT
A table with two columns that shows store opening and closing times, with each timezone.
Here's the table:
ShopId OpenAt CloseAt
1 09:00:00 -08 17:00:00 -08
2 09:30:00 -05 17:30:00 -05
3 08:00:00 -11 15:00:00 -11
4 10:00:00 +07 15:30:00 +07
What I need to know is if at moment (at my current GMT time), the shop is open. Taking into consideration that Saturday and Sunday it's closed.
I'm digging around and I got something like:
SELECT ((OpenAt,CloseAt) OVERLAPS(NOW())) AND ISODOW < 6
with no luck...
Thanks
Perez
Try this :
SELECT ((date_trunc('day',nowAtShopLocation)+"OpenAt"::time, date_trunc('day',nowAtShopLocation)+"CloseAt"::time) OVERLAPS(nowAtShopLocation,nowAtShopLocation)) and EXTRACT (ISODOW FROM nowAtShopLocation) <6
from (
select *,now() AT TIME ZONE 'UTC'+(EXTRACT(TIMEZONE_HOUR FROM "OpenAt")||' hour')::interval nowAtShopLocation from your_table
) a

Count of sales partitioned by DOW (with date and time as input) - postgresql

Have scoured the internet for right response, but am not finding what I want.
I have an example dataset as follows:
Date --------------------------------- Number of Sales
Saturday 9th September 13:22:00 ------ 1
Sunday 10th September 16:44:02 ------ 3
Monday 11th September 12:00:00 ------ 2
Tuesday 12th September 13:04:34 ------ 4
Wednesday 13th September 15:84:04 ---- 3
Thursday 14th September 16:30:00 ----- 9
Friday 15th September 17:00:00 ------ 3
Saturday 16th September 18:00:03 ----- 5
Sunday 17th September 12:00:34 ------- 2
I want the output to be a table as follows:
Day of week -------------- Count
Mon ---------------------- 2
Tues --------------------- 4
Wed ---------------------- 3
Thurs -------------------- 9
Fri ---------------------- 3
Sat ---------------------- 6
Sun ---------------------- 5
This is a small sample, the dates go much further back, but this should give you an idea.
I am using postresql, version 9.5.8
I've tried different variations such as date_trunc, and partition (but perhaps am not using it properly). I keep getting the wrong output. Essentially, I want to be able to make a bar chart of day of week and count.
Ive tried this:
SELECT count(s.created_at), date_trunc('day', s.created_at)
FROM "sales" s
GROUP BY date_trunc('day', s.created_at)
This however gives me the count per unique day, rather than simply by dow, irrespective of date.
Thank you in advance.
https://www.postgresql.org/docs/current/static/functions-datetime.html
date_part or extract should do:
SELECT count(s.created_at), extract(dow from s.created_at)
FROM "sales" s
GROUP BY extract(dow from s.created_at)

Month to date aggreate KPI query postgresql

I'm trying to find a way to obtain the amount of sales made from month to month but only comparing the aggregate total up to the current month's date.
In other words, I want to compare this month's sales up until now, against other months sales up until that month's same day.
Example using today's date as a reference (2016-06-18):
Total sales on January 2016 (*From 2016-01-01 to 2016-01-31*): 1000
Total sales on January 2016 (*From 2016-01-01 to 2016-01-17*): 650
Total sales on February 2016 (*From 2016-02-01 to 2016-01-17*): 670
Total sales on July 2016 (*From 2016-06-01 to current_date - 1*): 680
The structure of my data is as follows:
date sales
2016-01-01 5
2016-01-02 4
2016-01-03 5
2016-01-04 7
.
.
.
When I run the query I would like to have a monthly comparison of the totals mentioned above, so a result that looks like this:
month sales
2016-01 650
2016-02 670
.
.
2016-06 680
So comparing the month-to-date total of each month.
This is what I have tried so far and it seems to be fine, but somehow I always get a small difference whenever I make tests for limit days like the first of each month or the last.
select
order_month,
sum(sales) as sales
from table
where extract (day from order_date::date)
<=
extract (day from current_date::date)
- case when extract (day from current_date::date)=1 then 0 else 1 end
group by 1;

Extract matching year for week number in postgresql

In postgresql extract(week from '2014-12-30'::timestamp) gives week number 1 of 2015. How do I extract the associated year that corresponds to the week number? Using extract(year ... gives 2014
Since week is the ISO-defined week, you want the isoyear:
#= select extract(isoyear from '2014-12-30'::timestamp);
date_part
-----------
2015
(1 row)
From the docs:
By definition, ISO weeks start on Mondays and the first week of a year
contains January 4 of that year. In other words, the first Thursday of
a year is in week 1 of that year.
In the ISO week-numbering system, it is possible for early-January
dates to be part of the 52nd or 53rd week of the previous year, and
for late-December dates to be part of the first week of the next year.
For example, 2005-01-01 is part of the 53rd week of year 2004, and
2006-01-01 is part of the 52nd week of year 2005, while 2012-12-31 is
part of the first week of 2013. It's recommended to use the isoyear
field together with week to get consistent results.
According to the postgresql documentation for extract week:
The number of the week of the year that the day is in. By definition
(ISO 8601), the first week of a year contains January 4 of that year.
(The ISO-8601 week starts on Monday.) In other words, the first
Thursday of a year is in week 1 of that year. (for timestamp values
only)
Based on this, you might have to do a little logic:
case when extract(week from '2014-12-30'::timestamp) = 1
and extract(month from '2014-12-30'::timestamp) = 12
then extract(year from '2014-12-30'::timestamp)+1
else extract(year from '2014-12-30'::timestamp)
end

SAS - Creating a week variable

I'm using SAS 9.3
I need to create a way to sum up by week total, and I have no idea how to do it. So basically I have a year list of dates (left column below) with a total from that date (the right column). Our week goes from Friday to the previous Thursday (e.g. Thursday Oct 17 through Friday the Oct 25th).
An issue I also have is as you see the dates on the left are not completely daily and don't always have a Thursday date before the last Friday date. Would any know a way to add these weeks up - Week 1, Week 2, etc etc ...?
Thanks for any help that can be provided
2013-01-01 3
2013-01-02 8
2013-01-03 8
2013-01-04 10
2013-01-06 1
2013-01-07 10
2013-01-08 14
2013-01-09 12
2013-01-10 8
2013-01-11 9
2013-01-12 1
2013-01-14 12
2013-01-15 8
2013-01-16 5
2013-01-17 15
2013-01-18 7
2013-01-20 1
Trivial way:
data want;
set have;
weekno = ceil((date-'03JAN2013'd)/7);
run;
IE, subtract the first thursday and divide by 7, (so 1/1-1/3 is weekno=0).
INTCK function is also adept at calculating this. The basic structure is
weekno=intck('WEEK.5','04JAN2013'd,date); *the second argument is when you want your first week to start;
WEEK means calculate weeks, # on left side of decimal is multiple week groups (2 week periods is WEEK2.), on right side is shift index (from the default sunday-saturday week).
You could also create a format that contained your weeks, and use that.