creating weekly buckets in date column in sql - sql-server-2012

How can i create weekly buckets for a date column.
My data looks like :
ID LOC DATE Amount
1 AAA 21-07-2015 3000
2 AAA 22-07-2015 1000
3 AAA 23-07-2015 0
4 AAA 27-07-2015 300
5 AAA 29-07-2015 700
I also have a Financial Year Calendar file containing the week start and end ranges and which week each bucket falls on.It looks like
Year WeekStart WeekEnd Week
2015 20-07-2015 26-07-2015 1
2015 27-07-2015 02-08-2015 2
so on till 2020...
The task here is I have to group all the line items in A table fall under each bucket and find the amount value per week.
Output:
ID LOC WEEk Amount
1 AAA 1 4000
2 AAA 2 1000
Not sure how to start the process itself or how to link these both files.Kindly need your help.

You need here Correlated Subqueries https://technet.microsoft.com/en-us/library/ms187638(v=sql.105).aspx. Let's assume data is in table data, calendar in table calendar. Then your query will look like
select
loc, week, sum(amount)
from
(select
(select top 1 week from calendar t1 where t1.WeekStart <= t2.date and t2.date <= t1.WeekEnd) as week,
loc,
amount
from
data t2) as subsel1
group by
loc, week

Related

Query to find SUM based on week

I have a table like date , sales , region
date
Sales
Region
11/02/2021
20
1
12/02/2021
23
1
13/02/2021
30
2
14/02/2021
50
2
15/02/2021
10
3
16/02/2021
10
3
How to extract sum of sales per region based on weeks (Week starting from Monday to Sunday)
You need to select the week before grouping.
This should work for you:
SELECT DATEPART(week, date) AS Week,
FROM table
GROUP BY DATEPART(week, RegistrationDate);

SQL count recurring values per week

I've asked the same question for pandas: link
And now I'm struggling to do the same thing with Big Query SQL. This is what I'm trying to achieve:
I have a Table containing dates and ids that are grouped by weeks
items_per_week:
date id
2022-02-07 1
3
5
4
2022-02-14 2
1
3
2022-02-21 9
10
1
...
...
2022-05-16 ....
I want to count for each week how much of the id's are repeating from previous week
For example the desired output for the Table would be:
date count
2022-02-07 0
2022-02-14 2 # because id 1 and 3 are present in previous week
2022-02-21 1 # because id 1 is present in previous week
...
I tried grouping the id and counting for each id how many are repeating for each date but it didn't work out as planned.
Try doing self-join and counting the results:
SELECT t1.date
,COUNT(t2.id) as count
FROM Table t1
LEFT JOIN Table t2
ON t1.date = DATE_SUB(t2.date, INTERVAL 7 DAY) -- finding previous week
AND t1.id = t2.id -- identifying matching ids
GROUP BY 1
Couple assumptions here:
id is unique per week (i.e you can't have duplicates in a week of 2022-02-07)
date is iterated over 7 days period (i.e you have one date per week)

SQL - GROUP BY 3 values of the same column

I have this table in GBQ :
ClientID Type Month
XXX A 4
YYY C 4
FFX B 5
FFF B 6
XXX C 6
XXX A 6
YRE C 7
AAR A 7
FFF A 8
EGT B 8
FFF B 9
ETT C 9
I am counting the number of Type per ClientID and Month, with this basic query :
SELECT ClientID,
COUNT(DISTINCT Type) NbTypes,
Month
FROM Table
GROUP BY ClientID, Month
The result looks like this :
ClientID NbTypes Month
XXX 1 4
XXX 2 6
FFF 1 6
FFF 1 8
FFF 1 9
... ... ...
What I need to do is, count the number of Type per ClientID and for each Month : per the last 3 months.
For example :
For the ClientID = XXX, and Month = 8 : I want to have the count of Type where Month = 6 AND Month = 7 AND Month = 8
Is there a way to do this with GROUP BY ?
Thank you
You could use HAVING in your statement:
SELECT ClientID,
COUNT(DISTINCT Type) NbTypes,
Month
FROM Table
GROUP BY ClientID, Month
HAVING Month = EXTRACT(MONTH FROM CURRENT_DATE())
OR Month = EXTRACT(MONTH FROM DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 1 MONTH))
OR Month = EXTRACT(MONTH FROM DATE_SUB(DATE_TRUNC(CURRENT_DATE(), MONTH), INTERVAL 2 MONTH))
Note that in your table seems to be no column to determinate the year, so this statement will group all values with month value of the current month to current month minus two months. So for example every data from December, November and October 2021, 2020, 2019 etc. will be selected with this query.
Also note that I could not test this statement, since I don't use BigQuery.
Here is the source for the Date-Functions:
https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions
You can use a SELECT in a SELECT if that is allowed in Google Big Query
SELECT ClientID,
COUNT(DISTINCT Type) NbTypes,
Month,
MAX((select count(distinct Type)
from Table t2
where t1.ClientID=t2.ClientID
and t1.month-t2.month between 0 and 2
)
) as NbType_3_months
FROM Table t1
GROUP BY ClientID, Month
You can group rows by ClientID and Month, count the number of types and sort rows by ClientID in ascending order and by Month in descending order, and then select from each group the rows of the past three months. It is roundabout and complicated to handle such a scenario in SQL because SQL implements set-orientation only halfway up. For your case, you have to get the largest month for each ClientID, find the eligible records through a join filter, and perform grouping and count. The usual way is to fetch the original data out of the database and process it in Python or SPL. SPL, the open-source Java package, is easier to be integrated into a Java program and generate much simpler code. It gets the task done with only two lines of code:
A
1
=GBQ.query("SELECT CLIENTID, COUNT(DISTINCT TYPE) AS NBTYPES, MONTH FROM t2 GROUP BY CLIENTID, MONTH ORDER BY CLIENTID, MONTH DESC")
2
=A1.group#o(#1).run(m=~.#3-3,~=~.select(MONTH>m)).conj()

SQL query to find out number of days in a week a user visited

I'd like to find out how many days in a week users have visited my site. For example, 1 day in a week, 2 days in a week, every day of the week (7).
I imagine the easiest way of doing this would be to set the date range and find out the number of days within that range (option 1). However, ideally I'd like the code to understand a week so I can run a number of weeks in one query (option 2). I'd like the users to be unique for each number of days (ie those who have visited 2 days have also visited 1 day but would only be counted in the 2 days row)
In my database (using SQLWorkbench64) I have user ids (id) and date (dt)
I'm relatively new to SQL so any help would be very much appreciated!!
Expected results (based on total users = 5540):
Option 1:
Number of Days Users
1 2000
2 1400
3 1000
4 700
5 300
6 100
7 40
Option 2:
Week Commencing Number of Days Users
06/05/2019 1 2000
06/05/2019 2 1400
06/05/2019 3 1000
06/05/2019 4 700
06/05/2019 5 300
06/05/2019 6 100
06/05/2019 7 40
You can find visitor count between a date range with below script. Its also consider if a visitor visits multi days in the given date range, s/he will be counted for the latest date only from the range-
Note: Dates are used as sample in the query.
SELECT date,COUNT(id)
FROM
(
SELECT id,max(date) date
FROM your_table
WHERE date BETWEEN '04/21/2019' AND '04/22/2019'
GROUP BY ID
)A
GROUP BY date
You can find the Monday of the week of a date and then group by that. After you have the week day there is a series of group by. Here is how I did this:
DECLARE #table TABLE
(
id INT,
date DATETIME,
MondayOfWeek DATETIME
)
DECLARE #info TABLE
(
CommencingWeek DATETIME,
NumberOfDays INT,
Users INT
)
INSERT INTO #table (id,date) VALUES
(1,'04/15/2019'), (2,'07/21/2018'), (3,'04/16/2019'), (4,'04/16/2018'), (1,'04/16/2019'), (2,'04/17/2019')
UPDATE #table
SET MondayOfWeek = CONVERT(varchar(50), (DATEADD(dd, ##DATEFIRST - DATEPART(dw, date) - 6, date)), 101)
INSERT INTO #info (CommencingWeek,NumberOfDays)
SELECT MondayOfWeek, NumberDaysInWeek FROM
(
SELECT id,MondayOfWeek,COUNT(*) AS NumberDaysInWeek FROM #table
GROUP BY id,MondayOfWeek
) T1
SELECT CommencingWeek,NumberOfDays,COUNT(*) AS Users FROM #info
GROUP BY CommencingWeek,NumberOfDays
ORDER BY CommencingWeek DESC
Here is the output from my query:
CommencingWeek NumberOfDays Users
2019-04-14 00:00:00.000 1 2
2019-04-14 00:00:00.000 2 1
2018-07-15 00:00:00.000 1 1
2018-04-15 00:00:00.000 1 1

Return rows if the column value is different than the previous days record

I want a select query that returns me all rows for the current day, only if the 'amount' is different that the previous days.
sales
-id
-user_id
-amount
-datetime
The sales table gets a new record for each user_id daily.
An example scenerio would be as follows:
5 123 700 2017/01/05
4 123 500 2017/01/04
3 123 1500 2017/01/03
2 123 1500 2017/01/02
1 123 500 2017/01/01
So if you search for records on the Jan. 5th, you will get 1 row since it is different that the previous days (700 vs 500).
result:
5 123 700 2017/01/05
But if you were run the query on the 3rd, since the amound $1500 is the same as on the 2nd, you will get 0 results back.
I have this basic join but I need to somehow compare the current days row from s1 and compare that with the previous days amount value.
select s1.*
from sales as s1
inner join sales s2 on s1.user_id = s2.user_id and s1.datetime = s2.datetime
You basically have the query. You just need the date arithmetic:
select s.*
from sales s left join
sales sprev
on sprev.user_id = s.user_id and sprev.datetime = dateadd(day, -1, s.datetime)
where s.datetime = '2018-01-05' and
(s.amount <> sprev.amount or sprev.amount is null);