SQL query : Sum a column (not the date column) for day, week to date, month to date, etc - sql

I am wondering if there is a way within one SQL statement if you can break out a sum of a total column by date, week to date, month to date, etc.
Sample data
DataDate TimeInterval TotalCalls
9/1/2014 12:00 154
9/1/2014 15:15 25
9/2/2014 07:30 125
9/3/2014 11:45 8
9/8/2014 10:15 15
9/9/2014 19:30 6
9/9/2014 12:15 100
In this case, I would want the select statement to return the following data for a given date of 9/9/2014 and week starting on Monday, 9/8/2014
Time Interval SumofCalls
Today 106
WTD 121
MTD 433
I have thought a CASE WHEN would work, but I can only find examples of how to use a CASE WHEN to sum the count of the date column being queried against the criteria. Any suggestions? Thanks!

Here's a way to do it in SQL Server using UNION and getting each range.
SQL Fiddle Demo
DECLARE #today DATE = CAST(GETDATE() AS DATE)
SELECT 'Today' AS 'TimeInterval',
SUM(TotalCalls) AS 'SumOfCalls'
FROM yourTable
WHERE DataDate = #today
UNION ALL
SELECT 'WTD',
SUM(TotalCalls)
FROM yourTable
WHERE DataDate BETWEEN dateadd(week, datediff(week, 0, #today), 0) AND #today
UNION ALL
SELECT 'MTD',
SUM(TotalCalls)
FROM yourTable
WHERE DataDate BETWEEN DATEADD(dd,-(DAY(#today)-1),#today) AND #today
If you could have the times periods go across the top as columns instead of rows then you could use CASE.

Related

BIGQUERY SQL How to count date range per hour total

I want to count total number of placed orders between date range 01 -31 days per hour in a day
Customer_placed_order_datetime
01 01:10:38
01 01:12:38
02 01:14:30
31 23:42:22
Example outcome would be like
Date 01-31
Date 01-31 total orders
1 hour 500
2 hour 300
and so forth.. Thank you
Consider below approach
select
format_datetime('%Y-%m', Customer_placed_order_datetime) year_month,
extract(hour from Customer_placed_order_datetime) hour,
count(*) total_orders
from your_table
group by year_month, hour
if applied to sample data as in your question
with your_table as (
select datetime '2021-12-01 01:10:38' Customer_placed_order_datetime union all
select '2021-12-01 01:12:38' union all
select '2021-12-02 01:14:30' union all
select '2021-12-31 23:42:22'
)
output is

how to generate a table of Monday dates that from a specific Monday to current date in sql

In SQL Server I need to generate a table of Mondays up to the current date.
The starting date is always 2020-04-27, which is a Monday.
For example, if today is 2020-05-25, I need a table like below:
date
0 2020-04-27
1 2020-05-04
2 2020-05-11
3 2019-05-18
4 2019-05-25
If today's date is 2020-05-23, then it's:
date
0 2020-04-27
1 2020-05-04
2 2020-05-11
3 2019-05-18
How I can produce the table like that?
You can use a recursive CTE to generate the list of dates:
WITH mondays AS (
SELECT CAST('2020-04-27' AS date) AS monday
UNION ALL
SELECT DATEADD(WEEK, 1, monday)
FROM mondays
WHERE DATEADD(WEEK, 1, monday) <= GETDATE()
)
SELECT *
FROM mondays
Output:
monday
2020-04-27
2020-05-04
2020-05-11
2020-05-18
Demo on dbfiddle
Note that if you want to generate a list of more than 100 dates, you will need to increase the maximum recursion level (which defaults to 100). This can be done by adding OPTION (MAXRECURSION 0) to the end of the query i.e.
SELECT *
FROM mondays
OPTION (MAXRECURSION 0)
Use master..spt_values this default table to attain this
DECLARE #DATEFROM DATE ='2020-04-27',
#DATETO DATE= '2020-05-25'
SELECT ALLDATES AS MONDATES FROM
(SELECT DATEADD(D, NUMBER, #DATEFROM) AS ALLDATES FROM MASTER..SPT_VALUES
WHERE TYPE = 'P' AND NUMBER BETWEEN 0 AND DATEDIFF(DD, #DATEFROM, #DATETO)) AS D1
WHERE DATENAME(DW, D1.ALLDATES)IN('MONDAY')

how to count a column by month if the date column has time stamp?

I have two columns in a table:
id date
1 1/1/18 12:55:00 AM
2 1/2/18 01:34:00 AM
3 1/3/18 02:45:00 AM
How do I count the number of IDs per month if the time is appended into the date column?
The output would be:
Count month
3 1
In ANSI SQL, you would use:
select extract(month from date) as month, count(*)
from t
group by extract(month from date);
I think more databases support a month() function rather than extract(), though.
you have to extract month and count by using group by
select DATE_PART('month', date) as month,count(id) from yourtable
group by DATE_PART('Month', date)

SQL Query to only pull one record for first day of month, for every month

I have a table that has one record per day. E.g. (this is just the date col of the table)
2018-07-08 03:00:00
2018-07-07 03:00:00
2018-07-06 03:00:00
2018-07-05 03:00:00
2018-07-04 03:00:00
2018-07-03 03:00:00
2018-07-02 03:00:00
2018-07-01 03:00:00
2018-06-30 03:00:00
2018-06-29 03:00:00
This data goes back a few years
I want to pull just the first day of month record, for all months in the table.
What is the SQL to do that?
(On SQL Server 2014)
I would use the day() function:
select t.*
from t
where day(t.MyDate) = 1;
Neither this nor datepart() are ANSI/ISO-standard, but there are other databases that support day(). The standard function is extract(day from t.MyDate).
If you want the first record in the table for each month -- but for some months, that might not be day 1 -- then you can use row_number(). One method is:
select top (1) with ties t.*
from t
order by row_number() over (partition by year(mydate), month(mydate) order by day(mydate) asc);
If all your time are zeroed all you do need is to get everything where DATEPART is first day.
select * from dbo.MyTable mt where DATEPART(day, mt.MyDate) = 1
It will work if you got one row per day. Off course you will need to use DISTINCT or an aggregation if you got more than one row per day.
You can use row_number() function :
select *
from (select *, row_number() over (partition by datepart(year, date), datepart(month, date) order by datepart(day, date)) seq
from table
) t
where seq = 1;
Perhaps you also need year in partition clause.
Though this has been answered, you can use date from parts in MS SQL as well.
create table #temp (dates date)
insert into #temp values ('2018-01-02'),('2018-01-05'), ('2018-01-09'), ('2018-01-10')
select * from #temp
dates
2018-01-02
2018-01-05
2018-01-09
2018-01-10
You can use this to get beginning of the month
select DATEFROMPARTS(year(dates), month(dates), 01) Beginningofmonth from #temp
group by DATEFROMPARTS(year(dates), month(dates), 01)
Output:
Beginningofmonth
2018-01-01

Postgres group by timestamp into 6 hourly buckets

I have the following simple table:
ID TIMESTAMP VALUE
4 2011-05-27 15:50:04 1253
5 2011-05-27 15:55:02 1304
6 2011-05-27 16:00:02 1322
7 2011-05-27 16:05:01 1364
I would like to average the VALUES, and GROUP each TIMESTAMP day into 6 hourly buckets. e.g 00:00 to 06:00, 06:00 to 12:00, 12:00 to 18:00 & 18:00 to 00:00.
I am able to group by year, month, day & hour using the following query:
select avg(VALUE),
EXTRACT(year from TIMESTAMP) AS year,
EXTRACT(month from TIMESTAMP) AS month,
EXTRACT(day from TIMESTAMP) as day
from TABLE
group by year,month,day
But I am unable to group each day into 4 periods as defined above, any help is most welcome.
I think grouping the integer value of the quotient of the (Hour of your timestamp / 6) should help. Try it and see if it helps.
Your group by should be something like
group by year, month, day, trunc(EXTRACT(hour from TIMESTAMP) / 6)
The logic behind this is that when the hour part of the date is divided by 6, the int values can only be
0 - 0:00 - 5:59:59
1 - 6:00 - 11:59:59
2 - 12:00 - 17:59:59
3 - 18:00 - 23:59:59
Grouping using this should put your data into 4 groups per day, which is what you need.