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)
Related
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
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.
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
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
We are building a cube for the business who analyse Sales against Stock.
I need a separate measure which will show the Closing Stock Qty.
The business runs in retail periods which contain retail weeks. The week always finishes on a Sunday, so my closing stock quantity needs to be from the Sunday.
So if we are looking at sales against today (Tuesday, 12th July 2016), then the column should show the value for the Sunday just passed, which is Sunday, 10th July 2016.
This needs to be dynamic depending on the level the user is viewing the data at.
If the lowest level is shown at the day level, then for all days for that week, it should show the previous Sunday's value.
If the lowest level is shown at the week level, then each week should show the previous weeks closing balance
Etc
, if the user is not breaking the pivot table down by date, but just retail weeks, then it should show the value for the last day of the previous week.
Same rules if the user was breaking the pivot table down to the level of period- it should show the value for the last day of the previous
We have a Date dimension with the following relevant hierarchies:
Calendar
Calendar Year
Calendar Quarter
Calendar Month
Date
Retail
Retail Year
Retail Period
Retail Week
Date
I know I can use ClosingPeriod function for this but I am having trouble with the Syntax.
I have the below but am getting NULL's. This is my first real MDX calculation so very new to this!
WITH MEMBER [Measures].[Closing On Hand Qty] AS
(
ClosingPeriod(
[Date].[Retail].[Retail Week],
[Date].[Retail].CurrentMember
),
[Measures].[On Hand Qty]
)
SELECT
[Date].[Retail].[Date].Members ON ROWS,
{
[Measures].[On Hand Qty],
[Measures].[Closing On Hand Qty]
} ON COLUMNS
FROM
Retail
WHERE
[Date].[Retail Year].&[2017]
(note: it doesn't throw an exception but the mdx standard is to state columns before rows in the Select clause)
ClosingPeriod I've not played with but something like the following might help:
WITH
MEMBER [Measures].[Closing On Hand Qty] AS
(
TAIL(
DESCENDANTS(
EXISTING [Date].[Retail].[Retail Week],
[Date].[Retail].[Date]
)
).ITEM(0).ITEM(0)
,[Measures].[On Hand Qty]
)
SELECT
{
[Measures].[On Hand Qty],
[Measures].[Closing On Hand Qty]
} ON 0,
[Date].[Retail].[Date].MEMBERS ON 1
FROM Retail
WHERE [Date].[Retail Year].&[2017];
Looking at the docs for ClosingPeriod I think something like the following might work:
WITH MEMBER [Measures].[Closing On Hand Qty] AS
(
ClosingPeriod(
[Date].[Retail].[Date],
EXISTING [Date].[Retail].[Retail Week]
),
[Measures].[On Hand Qty]
)
SELECT
{
[Measures].[On Hand Qty],
[Measures].[Closing On Hand Qty]
} ON COLUMNS,
[Date].[Retail].[Date].Members ON ROWS
FROM Retail
WHERE [Date].[Retail Year].&[2017];