SQL Server 2008 - Grouping results into 5 minute intervals - sql-server-2008

I currently have a SQL script that returns the results of data items that are processed into the database from imported files, however we are looking at getting a count of the number of items that come into the database broken into 5 minute intervals, for a defined day.
My existing script is as follows:
declare #date datetime
set #date = '2016-12-07 00:00:00.000
Select filename, IE.dateprocessingstarted
from tdii_inboundprocessed IE
inner join consignmentpf cpf
on ie.inboundfileprocessedid = cpf.inboundprocessedid
where 1=1 and (ie.dateprocessingstarted between `#date` and `dateadd(dd,1,#date)`
This returns the following:
FilenameDate ProcessingStarted
GOOD813546 2016-12-07 00:02:00
GOOD813546 2016-12-07 00:02:00
GOOD813546 2016-12-07 00:02:00
GOOD813546 2016-12-07 00:02:00
GOOD813546 2016-12-07 00:02:00
GOOD813546 2016-12-07 00:02:00
GOOD813554 2016-12-07 00:08:00
GOOD813554 2016-12-07 00:08:00
GOOD813554 2016-12-07 00:08:00
GOOD813554 2016-12-07 00:08:00
What I'd like to see is:
datetime numberoffiles
2016-12-07 00:05:00 6
2016-12-07 00:10:00 4
etc
the tdii_inboundprocessed table contains the details of files coming into the system, including the time we are interested in dateprocessingstarted) the consignmentpf table contains the details of items within a particular file and this is the number we are interested in getting a count of.
Thank you for any help

SELECT t.date ,
COUNT(*)
FROM ( SELECT DATEADD(MINUTE,
( ( DATEDIFF(MINUTE, #date,
IE.dateprocessingstarted) / 5 ) * 5 )
+ 5, #date) [date]
FROM #tdii_inboundprocessed IE
INNER JOIN consignmentpf cpf ON IE.inboundfileprocessedid = cpf.inboundprocessedid
WHERE 1 = 1
AND ( IE.dateprocessingstarted BETWEEN #date
AND DATEADD(dd, 1,
#date) )
) AS t
GROUP BY t.date;

Related

MySQL query to find hour of the day when the number of housing society visits is highest

Housing Society Visit Data
Id
Contact
Entry_time
Exit_time
Duration of Stay
1
8080808080
26/07/2021 08:00:05
26/07/2021 08:23:06
181
2
9692596925
26/07/2021 08:12:49
26/07/2021 08:14:44
115
3
7099270992
26/07/2021 11:02:49
26/07/2021 11:14:44
715
4
8900289002
26/07/2021 16:12:49
26/07/2021 16:14:44
115
5
9089590895
26/07/2021 15:12:49
26/07/2021 15:14:44
115
6
8765087650
26/07/2021 19:12:49
26/07/2021 19:14:44
115
7
7862178621
26/07/2021 18:12:49
26/07/2021 18:14:44
115
Visit data is available for many years and can contain millions of rows, so the solution should have a low time complexity.
Expected output: 8-9 AM (since highest number of visits (2) are made during that hour).
As I read the question this would help you very much on the way.
There are a couple of things you can do to improve this tho:
Create separate table with hours to avoid the unions (or do it with numbers table);
Store times separatly, the TIME() method slows the query.
.
SELECT
hours.`hour`,
COUNT(occurrence.perfId) AS occurrences
FROM (
SELECT '00:00' AS `hour`
UNION SELECT '01:00'
UNION SELECT '02:00'
UNION SELECT '03:00'
UNION SELECT '04:00'
UNION SELECT '05:00'
UNION SELECT '06:00'
UNION SELECT '07:00'
UNION SELECT '08:00'
UNION SELECT '09:00'
UNION SELECT '10:00'
UNION SELECT '11:00'
UNION SELECT '12:00'
UNION SELECT '13:00'
UNION SELECT '14:00'
UNION SELECT '15:00'
UNION SELECT '16:00'
UNION SELECT '17:00'
UNION SELECT '18:00'
UNION SELECT '19:00'
UNION SELECT '20:00'
UNION SELECT '21:00'
UNION SELECT '22:00'
UNION SELECT '23:00'
) hours
LEFT JOIN YOUR_TABLE occurrence ON hours.`hour` BETWEEN TIME(occurrence.Entry_time) AND TIME(occurrence.Exit_time)
GROUP BY hours.`hour`
ORDER BY occurrences DESC
Would produce (Data from a test database):
[hour] [occurrences]
10:00 73554
11:00 67492
09:00 65679
08:00 63886
13:00 63565
12:00 62525
07:00 61500
14:00 53095
15:00 49017
16:00 41955
17:00 31991
18:00 21251
06:00 17591
19:00 13717
20:00 8532
21:00 4421
22:00 2050
23:00 818
05:00 796
04:00 561
01:00 175
03:00 123
02:00 120
00:00 23
To get the hour only just wrap with a query and select the first:
SELECT hour FROM (
# Paste query from above here...
) hourData
LIMIT 1;
I was able to get the required output using the following query:
SELECT HOUR(Entry_time) as hr FROM table_name GROUP BY HOUR(Entry_time) ORDER BY COUNT(*) DESC LIMIT 1;
Thanks to the solution by #nicholascarey: SQL to determine peak volume and hour for all days

How to count total by current year of current month in mysql

I have bellow snippet table format.
Table name:- wp_lead_count_freevendor
id entryid start_date end_date user_id count_set entry_date cancel_set_date
70 11392 2015-12-03 2015-12-03 3185 1 2015-12-03 2015-12-04
71 11393 2015-12-03 2015-12-03 3185 1 2015-12-03 2015-12-04
72 11394 2014-10-01 2014-10-01 3185 1 2014-10-01 2014-10-01
Here i want to calculate count total count_set column. of current month & year by start_date column WHERE user_id=3185.
suppose in start_date current year is 2015 & current month is 12:-
year month count total
2015 12 2
For user id 3185 of this month of year count_set total =2
so any body will tell how do i fire the query to get count_set total for current year of current month for user_id=3185.
I have tried bellow query but its not working.
$check_per_month=mysql_query("SELECT DATE_FORMAT(end_date, '%Y') as 'year',
DATE_FORMAT(end_date, '%m') as 'month',
COUNT(id) as 'total'
FROM wp_lead_count_freevendor WHERE user_id=$wp_lead_count_user_id
GROUP BY DATE_FORMAT(end_date, '%Y%m')") OR DIE(mysql_error());
while($row = mysql_fetch_assoc($check_per_month))
{
echo $sql_chk_current_month_count=$row['total'];
}
Try to count using the where , year and month methods like this:
SELECT .... WHERE YEAR(start_date)=2015 AND MONTH(start_date)=12
Try this query:
SELECT YEAR(NOW()) as `year`,MONTH(NOW()) as `month', SUM(count_set) as `count_set`
From wp_lead_count_freevendor
WHERE YEAR(start_date)=YEAR(NOW()) AND MONTH(start_date)=MONTH(NOW()) AND user_id=3185
group by YEAR(NOW()),MONTH(NOW())

How to get last 3 data of last 3 week days from a table

I have a table consisting of stock market's daily data. It consists of various number of rows for each day.I have a column named 'High' in the table. Now I need to calculate MAX(High) for last 3 week days. For ex:- if today is Wednesday I need to calculate MAX of last week's friday and this week's monday,tuesday. I know that I can do this if I know the date manually using a query like this.
Select MAX(HIGH) from table_name where date>='date'
But I don't want to do like this i just want to automate this with a program written in PHP. How can i Achieve this any help in both either PHP or SQL is appreciable. My table just has 6 columns
date,time,open,high,low,close
say suppose if my table is like this
date time open high low close
2015-05-06 09:30:00 2012.50 2020.5 2016.5 2014.0
2015-05-06 09:31:00 2013.50 2021.5 2014.5 2016.0
2015-05-06 09:32:00 2014.50 2021.75 2017.5 2013.0
2015-05-07 09:30:00 2011.50 2019.5 2018.5 2014.0
2015-05-07 09:31:00 2014.50 2022.5 2016.5 2015.0
2015-05-07 09:32:00 2012.50 2026.5 2017.5 2016.0
2015-05-08 09:30:00 2010.50 2024.5 2015.5 2017.0
2015-05-08 09:31:00 2013.50 2026.5 2017.5 2018.0
2015-05-08 09:32:00 2014.50 2028.5 2015.5 2019.0
2015-05-08 09:33:00 2014.50 2022.5 2017.5 2012.0
2015-05-11 09:30:00 2017.50 2025.5 2018.5 2013.0
2015-05-11 09:31:00 2018.50 2027.5 2019.5 2016.0
2015-05-11 09:32:00 2019.50 2024.5 2011.5 2017.0
2015-05-11 09:33:00 2020.50 2026.5 2017.5 2014.0
2015-05-12 09:30:00 2018.50 2023.5 2018.5 2018.0
2015-05-12 09:31:00 2017.50 2024.5 2017.5 2014.0
2015-05-12 09:32:00 2018.50 2023.5 2018.5 2013.0
2015-05-12 09:33:00 2017.50 2024.5 2019.5 2014.0
2015-05-12 09:34:00 2016.50 2023.5 2016.5 2012.0
2015-05-12 09:35:00 2017.50 2025.5 2018.5 2011.0
and if today's date is 2015-05-13(wednesday) I need MAX(high) of last 3 week days i.e 2015-05-12,11,08 which is 2028.5.
Presumably, you only have data on "week days".
select max(high)
from table_name t join
(select date
from table_name
group by date
order by date desc
limit 3
) dates
on t.date = dates.date;
Presumably, you either want a condition on the stock or a group by, but this is based on your sample query.
You can make this more efficient by adding a where clause. Typically, the last three working days would be within the last week, or so:
select max(high)
from table_name t join
(select date
from table_name
where date >= date_sub(curdate(), interval 7 day)
group by date
order by date desc
limit 3
) dates
on t.date = dates.date;
You can use date_sub function for this case:
select max(high) from table_name where date > date_sub(date, INTERVAL 3 DAY);
I think this is the correct query:
select top 3 date, max(high) from table_name order by date desc

Count 2 columns by the same grouping

I'm trying to get two counts of separate columns for data in one table.
I have a database that tracks issues, and one table, Issue, has the 2 relevant columns that each contain a date. Very similar to the following.
DateOpened DateClosed
2015-01-08 2015-01-08
2015-01-08 2015-01-08
2015-01-06 2015-01-08
2015-01-06 2015-01-08
2015-01-04 2015-01-07
2015-01-02 2015-01-07
2015-01-02 2015-01-07
My goal is to be able to count the number of entries opened and closed on each date. An example of the expected output from above would be.
Date CountDateOpened CountDateClosed
2015-01-08 2 4
2015-01-07 0 3
2015-01-06 2 0
2015-01-05 0 0
2015-01-04 1 0
2015-01-03 0 0
2015-01-02 2 0
I know I need to group by Date, but there should be days where more issues are closed than opened, but my COUNT(DateClosed) never seems to exceed my Count(DateOpened). I am doing on the fly date conversions in the query, but I do not believe them to be relevant since I always round to the nearest day. Here is the query I'm running so far, skinned down for simplicity.
SELECT
CREATEDATE AS [Date],
COUNT(CREATEDATE) AS [Number Opened],
COUNT(CLOSEDATE) AS [Number Closed]
FROM
ISSUE
GROUP BY
CREATEDATE
ORDER BY
[Date] DESC
One way of doing this is to use union all to create a single column for both dates and then group according to its type:
SELECT `Date`,
COUNT(`open`) AS `CountDateOpened`
COUNT(`closed`) AS `CountDateClosed`
FROM (SELECT `DateOpened` AS `Date`, 1 AS `open`, NULL AS `closed`
FROM `issue`
UNION ALL
SELECT `DateClosed` AS `Date`, NULL AS `open`, 1 AS `closed`
FROM `issue`
) t
GROUP BY `Date`
ORDER BY `Date` DESC
Try this
select
d.dt,(select COUNT(DateOpened) ct from ISSUE where
CAST(DateOpened as DATE)=CAST(d.dt as DATE) )
,(select COUNT(DateClosed) ct from ISSUE where
CAST(DateClosed as DATE)=CAST(d.dt as DATE) )
from (
select number,DATEADD(D,number-7,GETDATE()) dt
from master.dbo.spt_values sp
where type='P' and DATEADD(D,number-7,GETDATE())<'2015-01-09'
)
d
ORDER BY d.dt desc
OUTPUT
Date DateOpened DateClosed
2015-01-08 2 4
2015-01-07 0 3
2015-01-06 2 0
2015-01-05 0 0
2015-01-04 1 0
2015-01-03 0 0
2015-01-02 2 0
Same as Mureinik's answer, just a little less typing...
SELECT date,SUM(status='opened') opened, SUM(status = 'closed') closed
FROM
( SELECT dateopened date,'opened' status FROM my_table
UNION ALL
SELECT dateclosed,'closed' FROM my_table
) x
GROUP
BY date DESC;

mysql get average data for full months

Given the following sample data:
tblData
Date Sales
----------------------
2011-12-01 122
2011-12-02 433
2011-12-03 213
...
2011-12-31 235
2011-11-01 122
2011-11-02 433
2011-11-03 213
...
2011-11-30 235
2011-10-10 122
2011-10-11 433
2011-10-12 213
...
2011-10-31 235
Notice that October data begins at 10 October, whereas subsequent months have complete data.
I need to get the average monthly sales over all complete months, which in this case would be November and December 2011.
How would I do this?
SELECT `date`, AVG(`sales`)
FROM sales
GROUP BY YEAR(`date`), MONTH(`date`)
HAVING COUNT(`date`) = DAY(LAST_DAY(`date`));
Example
If you want to limit the result, either
HAVING ...
ORDER BY `date` DESC LIMIT 3
which should always return data for the 3 most recent months, or something like
FROM ...
WHERE DATE_FORMAT(CURDATE() - INTERVAL 3 MONTH, '%Y-%m')
<= DATE_FORMAT(`date`, '%Y-%m')
GROUP BY ...
which should return data for the 3 previous months, if there is any. I'm not sure which is better but I don't believe WHERE gets to use any index on date, and if you're using DATETIME and don't format it you'll also be comparing the days and you don't want that,
Can't test it right now, but please have a try with this one:
SELECT
DATE_FORMAT(`Date`, '%Y-%m') AS yearMonth,
SUM(Sales)
FROM
yourTable
GROUP BY
yearMonth
HAVING
COUNT(*) = DAY(LAST_DAY(`Date`)