MySQL Count Numbers Are Off - mysql

I am not sure why my numbers are drastically off from each other.
A query with no max id:
SELECT id, DATE_FORMAT(t_stamp, '%Y-%m-%d %H:00:00') as date, COUNT(*) as count
FROM test_ips
WHERE id > 0
AND viewip != ""
GROUP BY HOUR(t_stamp)
ORDER BY t_stamp ASC;
I get:
1 2012-07-18 19:00:00 1313
106 2012-07-18 20:00:00 1567
107 2012-07-19 09:00:00 847
225 2012-07-19 10:00:00 5095
421 2012-07-19 11:00:00 205
423 2012-07-19 12:00:00 900
461 2012-07-19 13:00:00 619
490 2012-07-20 15:00:00 729
575 2012-07-20 16:00:00 1682
1060 2012-07-20 17:00:00 2063
2260 2012-07-20 18:00:00 1417
5859 2012-07-20 21:00:00 1303
7060 2012-07-20 22:00:00 1340
8280 2012-07-20 23:00:00 1211
9149 2012-07-21 00:00:00 1675
10418 2012-07-21 01:00:00 721
11127 2012-07-21 02:00:00 825
But if I add a max id:
AND id <= 8279
I get:
1 2012-07-18 19:00:00 1313
106 2012-07-18 20:00:00 1201
107 2012-07-19 09:00:00 118
225 2012-07-19 10:00:00 196
421 2012-07-19 11:00:00 2
423 2012-07-19 12:00:00 38
461 2012-07-19 13:00:00 20
490 2012-07-20 15:00:00 85
575 2012-07-20 16:00:00 483
1060 2012-07-20 17:00:00 1200
2260 2012-07-20 18:00:00 1200
5859 2012-07-20 21:00:00 1201
7060 2012-07-20 22:00:00 1220
The numbers are WAY off from each other. Something is goofy.
EDIT: Here is my table structure:
id t_stamp bID viewip unique
1 2012-07-18 19:22:20 5 192.168.1.1 1
2 2012-07-18 19:22:21 1 192.168.1.1 1
3 2012-07-18 19:22:22 5 192.168.1.1 0
4 2012-07-18 19:22:22 3 192.168.1.1 1

You are not grouping by ID and I think you intend to.
Try:
SELECT id, DATE_FORMAT(t_stamp, '%Y-%m-%d %H:00:00') as date, COUNT(*) as count
FROM test_ips
WHERE id > 0
AND viewip != ""
GROUP BY id, DATE_FORMAT(t_stamp, '%Y-%m-%d %H:00:00')
ORDER BY t_stamp;

Your query is not consistent.
In your select statement you are displaying the full date.
But you are grouping your data by the hour. So your count statement is taking the count of all the data for each hour of the day.
As an example take your first result:
1 2012-07-18 19:00:00 1313
The count of 1313 contains the records for all of your dates (7/18, 7/19, 7/20, 7/21, 7/22, etc) that have an hour of 19:00.
But the way you have your query setup, it looks like it should be the count of all records for 2012-07-18 19:00:00.
So when you add AND id <= 8279" The dates of 7/21 and some of 7/20 or no longer being counted so your count values are now lower.
I'm guessing you are meaning to group by the date and hour and not just the hour.

Related

Group By 3 columns (JobId, StartTime, EndTime) for continuous days in MySQL

I want to group by the JobId, StartTime & EndTime only for continuous days. If a specific row doesn't form part of a range it should be discarded. The Id's should also pivot into a column per grouping.
Id
Date
StartTime
EndTime
JobId
1
2021-08-23
08:30:00
19:00:00
1
2
2021-08-24
08:30:00
19:00:00
1
3
2021-08-24
12:30:00
14:30:00
2
4
2021-08-24
15:30:00
19:00:00
1
5
2021-08-25
08:30:00
19:00:00
1
6
2021-08-25
12:30:00
14:30:00
2
7
2021-08-25
15:45:00
19:00:00
1
8
2021-08-26
08:30:00
09:30:00
1
9
2021-08-26
15:30:00
19:00:00
1
10
2021-08-26
10:30:00
11:00:00
1
11
2021-08-26
12:00:00
14:30:00
1
12
2021-08-27
08:30:00
09:30:00
1
13
2021-08-27
11:00:00
11:15:00
1
14
2021-08-27
11:30:00
14:30:00
1
15
2021-08-28
08:30:00
09:30:00
1
Using the above sample data you can see 3 groupings that can form such a continuous range.
Range 1 consists of Id's, 1,2 & 5 - 2021-08-23 to 2021-08-25, 08:30:00 to 19:00:00
Range 2 consists of Id's 3 & 6 - 2021-08-24 to 2021-08-25, 12:30:00 to 14:30:00
Range 3 consists of Id's 8, 12 & 15 - 2021-08-26 to 2021-08-28, 08:30:00 to 09:30:00
The end result should be:
JobId
StartDate
EndDate
StartTime
EndTime
Ids
1
2021-08-23
2021-08-25
08:30:00
19:00:00
1,2,5
2
2021-08-24
2021-08-25
12:30:00
14:30:00
3,6
1
2021-08-26
2021-08-28
08:30:00
09:30:00
8,12,15
MySQL 8.0.23
Assuming that JobId, `Date`, StartTime, EndTime is unique you may use:
SELECT JobId,
MIN(`Date`) StartDate,
MAX(`Date`) EndDate,
StartTime,
EndTime,
GROUP_CONCAT(Id) Ids
FROM test
GROUP BY JobId,
StartTime,
EndTime
HAVING COUNT(*) > 1
AND DATEDIFF(EndDate, StartDate) = COUNT(*) - 1
ORDER BY StartDate, StartTime
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=fce8590f72ac1d50cd9e89add3ed01e7

How to find the most appropriate date between overlapping date periods in mysql

I`w got an 2 tables with such data:
Table 1
id
s_id
s_date
1
33
2021-03-05 10:36:59
2
33
2021-03-06 10:36:59
3
33
2021-03-09 10:36:59
4
33
2021-03-10 13:36:59
5
33
2021-03-11 12:36:59
6
33
2021-03-12 09:00:59
7
33
2021-03-13 13:36:59
8
33
2021-03-14 18:00:00
9
33
2021-03-15 18:00:00
10
33
2021-03-16 13:00:00
11
33
2021-03-17 18:00:00
12
33
2021-03-18 14:00:00
13
33
2021-04-01 18:00:00
14
33
2021-05-02 14:00:00
Table 2
id
s_id
amount
date_from
date_to
1
33
100
2012-03-12 00:00:00
2022-01-01 00:00:00
2
33
200
2018-03-12 00:00:09
2021-02-28 00:00:00
3
33
300
2021-03-01 00:00:00
2021-03-31 00:00:00
4
33
400
2021-03-07 00:00:00
2021-03-12 00:00:00
How to select row with appropriate id where s_date between date_from and date_to most close to date_from\date_to range?
In my case most appropriate rows must be:
id
s_id
s_date
amount
1
33
2021-03-05 10:36:59
300
2
33
2021-03-06 10:36:59
300
3
33
2021-03-09 10:36:59
400
4
33
2021-03-10 13:36:59
400
5
33
2021-03-11 12:36:59
400
6
33
2021-03-12 09:00:59
400
7
33
2021-03-13 13:36:59
300
8
33
2021-03-14 18:00:00
300
9
33
2021-03-15 18:00:00
300
10
33
2021-03-16 13:00:00
300
11
33
2021-03-17 18:00:00
300
12
33
2021-03-18 14:00:00
300
13
33
2021-04-01 18:00:00
100
14
33
2021-05-02 14:00:00
100
Thank you!
You can get the mid date for each pair of date_from and date_to with:
(UNIX_TIMESTAMP(date_from) + UNIX_TIMESTAMP(date_to)) / 2
Then find the absolute difference from s_date and sort by that:
SELECT *
FROM tablename
ORDER BY ABS(UNIX_TIMESTAMP(s_date) - ((UNIX_TIMESTAMP(date_from) + UNIX_TIMESTAMP(date_to)) / 2))
You can apply LIMIT 2 to get the 2 most appropriate ids.
See the demo.
Do you want to filter for the rows using date comparisons? For your examples:
select t.*
from t
where s_date >= date_from and s.date < date_to;

How can I sort data from three datasets? (SSRS 2008)

I can't find solution how can I sort data form three datasets. I have one static dataset and two matrix tables which I want to connect in one report. Every table has the same ID which I can use to connect them (the same number of rows as well) but don't know how could I do this? Is it possibile to connect few datasets?
table1:
N ID St From To
1 541 7727549 08:30:00 14:00:00
2 631 7727575 07:00:00 15:00:00
3 668 7727552 09:00:00 17:00:00
4 679 18:00:00 00:00:00
5 721 17:00:00 00:00:00
table:2
ID P1 P2 P3 P4
541 12:00:00 - 12:10:00
631 08:45:00 - 08:55:00 11:30:00 - 11:40:00 13:00:00 - 13:15:00
668 12:05:00 - 12:15:00 13:45:00 - 13:55:00 14:55:00 - 15:10:00
679 21:15:00 - 21:30:00
721 20:40:00 - 20:50:00 21:50:00 - 22:05:00
table3:
ID W1 W2 W3
541 11:28:58 - 11:39:13
631 08:46:54 - 08:58:43 11:07:04 - 11:17:05
668 11:26:11 - 11:41:44
679
721 11:07:19 - 11:17:06

Overriding Data based on sub query

I have a Rates table that records the rate of a process
DateTime Rate
2013-11-25 05:00:00 22
2013-11-25 06:00:00 78
2013-11-25 07:00:00 33
2013-11-25 07:10:00 56
2013-11-25 08:30:00 12
and a Downtime table that records time periods where the above data may not be valid
StartDateTime EndDateTime
2013-11-25 04:59:00 2013-11-25 05:10:00
2013-11-25 07:00:00 2013-11-25 07:15:00
How can I get the following output where any Rate value recorded between any period in the Downtime table is replaced by a fixed value e.g. 50?
DateTime Rate
2013-11-25 05:00:00 50
2013-11-25 06:00:00 78
2013-11-25 07:00:00 50
2013-11-25 07:10:00 50
2013-11-25 08:30:00 12
This should do the trick:
SELECT r.datetime, if(d.startDatetime IS NULL, r.rate, 50) rate
FROM rates r
LEFT JOIN downtime d
ON r.datetime BETWEEN d.startDatetime AND d.endDatetime
Fiddle here.

Combine and sum up 3 minutes record to a single row of record

I have a table which will record data every minutes. It looks like:
time_stamp wh
2013-02-01 08:00:00 1700
2013-02-01 08:01:00 1600
2013-02-01 08:02:00 1800
2013-02-01 08:03:00 1700
2013-02-01 08:04:00 1900
2013-02-01 08:05:00 1400
2013-02-01 08:06:00 1500
2013-02-01 08:07:00 1700
2013-02-01 08:08:00 1700
2013-02-01 08:09:00 1800
2013-02-01 08:10:00 1800
2013-02-01 08:11:00 1400
..etc
I want to sum up every 3 minutes wh data and find the average every 3 minutes.
The output will look like:
time_stamp SUM(wh) AVG(wh)
2013-02-01 08:00:00 5100 1700
2013-02-01 08:03:00 5500 1833.3333
2013-02-01 08:06:00 4900 1633.3333
2013-02-01 08:09:00 5000 1666.6667
it seems easy but i can't get the result i want. This is the sql query i tried:
SELECT from_unixtime(ROUND(unix_timestamp(time_stamp) /
(60*3)) * 60 * 3) AS rounded_time,
SUM(wh),
AVG(wh)
FROM electrex_0
WHERE time_stamp BETWEEN '2013-02-01 08:00' AND '2013-02-01 09:00'
GROUP BY rounded_time
By using this sql code, I manage to get the time_stamp correctly but not for SUM and AVG. I realize it will sum up in another way.For Example:the Sum(wh) for 2013-02-01 08:03:00 is 5100 which it will take the data from 08:02,08:03,08:04 and sum it up.
Here is how you can do it with variables
SET #VAR:=1;
SET #group=0;
SELECT
time_stamp,
SUM(wh) AS `TotalSum`,
AVG(wh) AS `TotalAvg`
FROM
(
SELECT
time_stamp,
wh,
#VAR AS Level,
#group AS `TGroup`,
#group := IF(#VAR = 3,#group + 1 ,#group) ,
#VAR := IF(#VAR = 3,1,#VAR+1 )
FROM electrex_0
) AS l
GROUP BY TGroup
SQL Fiddle Demo
Output
| TIME_STAMP | TOTALSUM | TOTALAVG |
----------------------------------------------------------
| February, 01 2013 08:00:00+0000 | 5100 | 1700 |
| February, 01 2013 08:03:00+0000 | 5000 | 1666.6667 |
| February, 01 2013 08:06:00+0000 | 4900 | 1633.3333 |
| February, 01 2013 08:09:00+0000 | 5000 | 1666.6667 |
How do you want to get 5500 from:
2013-02-01 08:03:00 1700
2013-02-01 08:04:00 1900
2013-02-01 08:05:00 1400
It sums up to 5000, doesn't it?
Here is your query fixed to return correct data:
SELECT
from_unixtime(ROUND((unix_timestamp(time_stamp) - 60) / (60*3)) * 60 * 3) AS rounded_time,
SUM(wh),
AVG(wh)
FROM electrex_0
WHERE time_stamp BETWEEN '2013-02-01 08:00'
AND '2013-02-01 09:00'
GROUP BY rounded_time
Returns:
ROUNDED_TIME SUM(WH) AVG(WH)
February, 01 2013 08:00:00+0000 5100 1700
February, 01 2013 08:03:00+0000 5000 1666.6667
February, 01 2013 08:06:00+0000 4900 1633.3333
February, 01 2013 08:09:00+0000 5000 1666.6667
Demo