Redshift count number of Mondays in a given time range - postgresql

I want to use Redshift to count the number of Mondays in a given time range. I've tried using date_part, which returns the day of the week. I can't use a simple count as there are multiple instances on the same day.

if you have dates table reference you can use the following code
select count(distinct my_table.date)
from my_table
where
date_part(dow,my_table.date)=1
and my_table.date between '2015-01-01' and '2016-01-01'
in this case the query will count all Mondays during 2015,
you can change the dates range the the day week .
date_part(dow,my_table.date)=1 -- Monday
date_part(dow,my_table.date)=2 -- Tuesday
and so on
if you don't have dates table , you should create Cartesian product

Related

How to create a table containing all dates in a given year that are within a 7-day range of known dates (from a separate table)

I have a table (holidays) containing all the holidays in a year:
I need to make a table (t1) where 1 column contains all the 365 days within a year, and another column 'description' containing a name of a holiday for all dates that are within a +/- 7 day range of a holiday, and 'None' for all dates that are outside of this range.
I was able to use generate_series to create the first-column (my_date: all 365 days within a year) and used a left-join to try to create the second column (description)
WITH all_dates AS
SELECT my_date::date
FROM generate_series('2020-01-01', '2020-12-31', '1 day'::interval) my_date)
SELECT all_dates.my_date,
holidays.description
FROM all_dates
LEFT JOIN holidays
ON all_dates.my_date = holidays.holiday_date
To create the table below.
However, I need it to be such that 2020-01-02, 2020-01-02, ..., 2020-01-08 would have the description 'New Year's Day' as these dates are within a 7-day range of New Year's Day, and so forth for other days within a 7-day range of other holidays (e.g., rows for dates between 2020-12-18 to 2020-12-31 would have the description 'Christmas')
I'm also unsure about how to handle days that are within a 7-day range of more than one holiday (Father's Day and Independence Day have overlapping dates that are within a 7-day range). I need it to be such that there is only one row per day in 2020.
Any help would be appreciated!
Try something like below. You already have the ranges around the holidays, so use that in the join. Then, use distinct on to restrict results to one per calendar date, and adjust the order by to keep the holiday you want.
with all_dates as (
select my_date::date
from generate_series('2020-01-01',
'2020-12-31', '1 day'::interval) my_date
)
select distinct on (all_dates.my_date)
all_dates.my_date,
holidays.description
from all_dates
left join holidays
on all_dates.my_date
between holidays.holiday_date_min7
and holidays.holiday_date_plus7
order by all_dates.my_date,
abs(all_dates.my_date - holidays.holiday_date), -- keep closest
all_dates.my_date - holidays.holiday_date -- prefer upcoming holiday

convert interval to hours in monthly tables

I have 12 monthly tables, one for each month of the year 2019, records are order by an identifier (mmsi) and datetime (timestamp). I have calculated the interval (linetime2) between two consecutive rows. see below (August 2019):
Now I need to convert interval in hours in a new column. How can I do it? Can I run this:
SELECT EXTRACT(epoch FROM linetime2)/3600
or I have to take into account the number of days in a month and year?

Showing this year and last year's data in one row in PostgreSQL

I have a table of sales grouped by week. I want to write a query that creates a new table giving the sales of the week in question AND the sales of that item from this time last year, but my attempts either give blank cells for the this-time-last-year (TTLY) values or duplicates.
I've tried writing a subquery that takes the date, subtracts 52 weeks, and shows the value for that week, then joining that subquery to my main query.
However, that subquery isn't working: the query shows the date of a year ago correctly, but doesn't then pull the SALES for that TTLY week, only the current week.
with ttyl as
(select
date::date as date,
(sales.date - interval '52 weeks') as date_ttly,
ID,
value
from sales
where country = 'uk' and date > '2019-08-01' and ID = '12345678')
In this example the subquery generates the previous year's date in the date_ttly column but pulls 2019 data in the value column.
All the WHERE conditions are just temporary so as to make building the query easier.
Thank you!
Assuming that the sales are grouped by date and by country only, a join on the same table should work:
SELECT sales1.id,
sales1.date,
sales1.value,
sales2.date,
sales2.value
FROM sales AS sales1
JOIN sales AS sales2 ON sales1.date - interval '52 weeks' = sales2.date
AND sales1.country = sales2.country
However, this also assumes that your date is always the same day of the week, e.g. Monday.

how can i fetch recored week wise from between two dates in postgresql?

I am using this query for fetching the data day wise
SELECT
(count( server_time::timestamp::date)) ,
server_time::timestamp::date
FROM
complaint_details_v2
WHERE
server_time between '2018/10/03' and '2018/10/11'
GROUP BY
server_time::timestamp::date
ORDER BY
server_time ASC
but I want to alter the above query week wise instead of day wise between two dates.
you can group the dates into sevens by doing date arithmetic.
SELECT
(count( server_time::timestamp::date)) ,
min(server_time::timestamp::date) as "week starting"
FROM
complaint_details_v2
WHERE
server_time between '2018/10/03' and '2018/10/11'
GROUP BY
floor((server_time::timestamp::date - '2018/10/03'::date)/7)
ORDER BY
2 ASC
another alternative is grouping expression date_trunc(week,server_time) but that binds you to ISO weeks

How to Group By Week Across Year Boundary in TSQL

I use tsql to sum weekly data (starting date is Monday).
Last week spanned across the boundary of 2012 and 2013, which means that I get two weekly sums.
Is there a way to group the data within tsql so I get one weekly sum for 2012-12-31 to 2013-01-06?
Example data and sql:
http://sqlfiddle.com/#!6/52b25/13/0
No link example below. Hypothetical table has one column, "created" of datetime type. How many rows for each week? I'd like to get two result rows, one for the last solid week of 2012 and one for the week that 2013 starts in (which starts on Monday 12/31/2012).
select
min(created) as 'First Date',
count(*) as 'Count',
datepart(wk,created) as 'Week Number'
from items
group by datepart(wk,created), datepart(yy,created)
order by min(created)
One workaround is calculate week number manually
select
min(created) as 'First Date',
count(*) as 'Count',
datediff(dd,'2012-01-02',created)/7 AS week_number
from items
group by datediff(dd,'2012-01-02',created)/7 -- You may replace '2012-01-02' to any date that is Monday (start day of the week)
order by min(created)