This is not my query, its a query that someone wrote that i am now working with.
I have a database like so
id date high low open close open_id close_id
1 2009-05-01 00:00:00 0.729125 0.729225 0.72889 0.72889 1 74
2 2009-05-01 00:01:00 0.72888 0.728895 0.72883 0.72887 75 98
3 2009-05-01 00:02:00 0.728865 0.72889 0.72881 0.72888 99 121
4 2009-05-01 00:03:00 0.72891 0.72901 0.72891 0.729 122 141
5 2009-05-01 00:04:00 0.728975 0.729115 0.728745 0.72878 142 225
6 2009-05-01 00:05:00 0.728785 0.72882 0.72867 0.72882 226 271
7 2009-05-01 00:06:00 0.72884 0.72887 0.728735 0.728785 272 293
8 2009-05-01 00:07:00 0.728775 0.728835 0.72871 0.728835 294 317
9 2009-05-01 00:08:00 0.728825 0.72899 0.728795 0.72897 318 338
10 2009-05-01 00:09:00 0.72898 0.729255 0.72898 0.72922 339 383
11 2009-05-01 00:10:00 0.72922 0.729325 0.72908 0.729105 384 437
12 2009-05-01 00:11:00 0.729115 0.72918 0.728635 0.72905 438 553
(this is 12 out of about 200k rows)
This is my query
SELECT x.date, t.high, t.low, t.open, t.close, x.open_id, x.close_id from (SELECT MIN(`date`) as `date`, MAX(`close_id`) as `close_id`, MIN(`open_id`) as `open_id`
FROM `AUDNZD_minutes`
WHERE `date` >= '2011-03-07 00:00:00' and `date` < '2011-03-11 12:00:00'
GROUP BY round(UNIX_TIMESTAMP(date) / 600) order by `date`) as x inner join `AUDNZD_minutes` as t on x.close_id = t.close_id
It is selecting rows from that data base in 10 minute intervals. However I always have this Anomaly.
2011-03-07 00:00:00 1.3761 1.375595 1.375815 1.37589 55180489 55181083
2011-03-07 00:05:00 1.376055 1.37568 1.375925 1.37594 55181084 55181751
2011-03-07 00:15:00 1.37609 1.375835 1.375835 1.37606 55181752 55182003
2011-03-07 00:25:00 1.37578 1.37526 1.375505 1.375555 55182004 55182615
2011-03-07 00:35:00 1.374645 1.374455 1.374535 1.374645 55182616 55183178
2011-03-07 00:45:00 1.37463 1.373775 1.374085 1.374025 55183179 55183820
You can see that the diffrence between the first row and the second is 5 minutes and everythign after this is 10 minutes. this happens with any interval i try.
For example, 20 miunte intervals
2011-03-07 00:00:00 1.376155 1.375915 1.37594 1.376025 55180489 55181434
2011-03-07 00:10:00 1.376105 1.37592 1.37593 1.376085 55181435 55182273
2011-03-07 00:30:00 1.374025 1.37388 1.373965 1.37401 55182274 55183429
2011-03-07 00:50:00 1.373895 1.373595 1.37365 1.373595 55183430 55184894
2011-03-07 01:10:00 1.37382 1.373505 1.37373 1.373715 55184895 55185885
2011-03-07 01:30:00 1.373305 1.373025 1.373265 1.373055 55185886 55187306
How can i correct this query?
round function rounds numbers using basic math rules you probably learned in primary:
select FROM_UNIXTIME(round(UNIX_TIMESTAMP('2009-05-01 00:04:00') / 600) *600) from dual;
results with 2009-05-01 00:00:00 and
select FROM_UNIXTIME(round(UNIX_TIMESTAMP('2009-05-01 00:06:00') / 600) *600) from dual;
results with 2009-05-01 00:10:00, so you will always (on the provided dataset) have half of the interval in the first line if you keep using it.
Consider ceil or floor functions instead.
As a side note, #Strawberry made a point. Try to use anything like http://sqlfiddle.com/ to show some efforts in asking question at least.
Related
I have a table named pwrDay containing electric index counters (always growing).
jour
pwrconsohp
pwrconsohc
pwrprod
pwrprodmax
2021-09-26
35 736 527
18 073 331
12 629 677
0
2021-09-27
35 754 125
18 073 331
12 637 154
0
2021-09-28
35 780 113
18 073 331
12 646 963
0
2021-09-29
35 807 081
18 073 331
12 657 084
0
2021-09-30
35 833 193
18 073 331
12 668 804
0
2021-10-01
35 861 259
18 073 331
12 682 444
0
2021-10-02
35 888 342
18 073 331
12 693 908
0
2021-10-03
35 917 218
18 073 331
12 704 696
0
2021-10-04
35 944 869
18 073 331
12 706 056
0
2021-10-05
35 972 043
18 073 331
12 708 309
0
I need to extract the difference between previous and current row (maybe create a view?) The following query works for most days, but it's wrong every first day of month (or if I miss a control day):
SELECT pwr.jour,
(pwr.pwrconsoHP-ifnull(oldpwr.pwrconsoHP, 0)) as deltaconsoHP,
(pwr.pwrconsoHC-ifnull(oldpwr.pwrconsoHC, 0)) as deltaconsoHC,
(pwr.pwrProd-ifnull(oldpwr.pwrProd, 0)) as deltaProd
FROM pwrDay pwr
LEFT OUTER JOIN pwrDay oldpwr ON
(day(pwr.jour)-day(oldpwr.jour)=1 AND MONTH(pwr.jour)=MONTH(oldpwr.jour))
ORDER BY jour;
I also tried this query:
SELECT pwr.jour,
(pwr.pwrconsoHP-LAG(pwr.pwrconsoHP, 0)) as deltaconsoHP,
(pwr.pwrconsoHC-LAG(pwr.pwrconsoHC, 0)) as deltaconsoHC,
(pwr.pwrProd-LAG(pwr.pwrProd, 0)) as deltaProd
FROM pwrDay pwr
ORDER BY jour;
However, it doesn't run at all. I get this error message:
Erreur SQL (1305) : FUNCTION velbus.LAG does not exist
How can I write this query?
SELECT pwr.jour,
(pwr.pwrconsoHP-LAG(pwr.pwrconsoHP, 0) OVER(order by jour)) as deltaconsoHP,
(pwr.pwrconsoHC-LAG(pwr.pwrconsoHC, 0) OVER(order by jour)) as deltaconsoHC,
(pwr.pwrProd-LAG(pwr.pwrProd, 0) OVER(order by jour)) as deltaProd
FROM pwrDay pwr
ORDER BY jour;
give it a try ...
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;
I'm trying to filter, so the column salaryMonth only contains data which has 2020 inside, so 2019 is filtering out.
SELECT sum(km_amount) as total
, user_id
, salaryMonth
from kms
, users
where users.id = kms.user_id
group
by salaryMonth
, user_id
Did you try something like this?
SELECT
sum(km_amount) as total,
user_id,
salaryMonth
FROM kms, users
WHERE
users.id=kms.user_id
AND salaryMonth LIKE '%2020%'
GROUP BY
salaryMonth, user_id
You could save yourself no end of misery be refactoring your table as:
total user_id salary_yearmonth
625 64 2020-02-01
595 70 2020-02-01
600 74 2020-02-01
632 75 2020-02-01
471 77 2020-02-01
788 29 2019-03-01
35 4 2020-03-01
22 39 2020-03-01
373 47 2020-03-01
196 53 2020-03-01
140 74 2020-03-01
228 75 2020-03-01
49 29 2019-04-01
96 63 2019-05-01
406 4 2019-06-01
966 4 2019-07-01
514 1 2019-08-01
637 4 2019-08-01
580 47 2019-08-01
11 1 2019-09-01
I have 3 database tables with sample data given below
Meas_id - integer(Foreign keyed to Measurement.meas_id)
Tool_id - integer(Foreign keyed to Events.Machine_id)
Processdate- Timestamp with timezone (UTC)
CreatedDate- Timestamp with timezone (UTC)
Readings
Meas_id Tool_id Status Processdate
1 13 Completed 2016-01-01 01:34:11
1 28 Failed 2016-01-01 08:37:11
1 54 Failed 2016-01-02 16:04:12
1 32 Completed 2016-01-04 07:13:11
1 39 Completed 2016-01-04 14:14:14
1 12 Completed 2016-01-05 22:10:09
1 9 Completed 2015-12-28 13:11:07
1 17 Completed 2016-01-25 13:14:11
1 27 Completed 2016-01-15 14:15:16
1 31 Failed 2016-01-07 16:08:04
2 113 Completed 2016-01-01 01:34:11
2 128 Failed 2016-01-01 08:37:11
2 154 Failed 2016-01-02 16:04:12
2 132 Completed 2016-01-04 07:13:11
2 139 Completed 2016-01-04 14:14:14
2 112 Completed 2016-01-05 22:10:09
2 90 Completed 2015-12-28 13:11:07
2 117 Completed 2016-01-25 13:14:11
2 127 Completed 2016-01-15 14:15:16
2 131 Failed 2016-01-07 16:08:04
Events
Meas_id Machine_id Event_Name CreatedDate
1 13 Success 2015-12-27 01:34:11
1 17 Error 2015-12-27 08:37:11
1 28 Success 2015-12-27 16:04:12
1 9 Success 2015-12-28 07:13:11
1 54 Success 2015-12-28 14:14:14
1 31 Error 2015-12-28 22:10:09
1 32 Success 2015-12-29 13:11:07
1 39 Success 2015-12-29 13:14:11
1 12 Success 2015-12-31 14:15:16
1 27 Success 2016-01-01 16:08:04
2 113 Success 2015-12-27 01:34:11
2 117 Error 2015-12-27 08:37:11
2 128 Success 2015-12-27 16:04:12
2 90 Success 2015-12-28 07:13:11
2 154 Success 2015-12-28 14:14:14
2 131 Error 2015-12-28 22:10:09
2 132 Success 2015-12-29 13:11:07
2 139 Success 2015-12-29 13:14:11
2 112 Success 2015-12-31 14:15:16
2 127 Success 2016-01-01 16:08:04
Mesurement
Meas_id Meas_name
1 Length
2 Breadth
For each measurement ‘length’ and ‘breadth’ and each day of the week, I am trying to calculate the percentage of success in the first week of 2016 for all completed measurements of tools/machines within 168 hours of thier creation date.
My Desired Output is
Measurement DayofTheWeek PercentageSuccess
Length 1 50
Length 2 0
Length 3 0
Length 4 100
Length 5 100
Length 6 0
Length 7 0
Breadth 1 50
Breadth 2 0
Breadth 3 0
Breadth 4 100
Breadth 5 100
Breadth 6 0
Breadth 7 0
I tried doing it this way but certainly missing some logic and its not working.
Select m.Meas_name,
datepart(dd, Processdate) as DayofTheWeek,
(Count(m.Meas_name)* 100 / (Select Count(Event_Name) From Events where Event_Name = 'Success')) as PercentageSuccess
FROM Readings r JOIN
Measurements m
ON r.Meas_id = m.Meas_id
JOIN Events e
ON e.Meas_id = m.Meas_id
WHERE m.Meas_name IN ('Length', 'Breadth') AND
r.Status = 'Completed' AND
e.CreatedDate >= DATEADD(hh, -168, GETDATE())
GROUP BY m.Meas_name, datepart(dd, Processdate);
Kindly provide inputs on an optimized way of achieving it.
Nice I got downvoted for a correct answer probably because my answer wasn't very clear it is kind of hard to explain so here is an edit aimed at your comment and the downvoter (whom I think was just retaliating).
Anyway, Your joining of 3 tables while valid replicates the data in your events table. Due to that the way you are counting the records will always be exaggerated and incorrect. your calculation for percentage is also happens to be backwards.
On the join it looks like you are just missing the use of the Tool_id in your join. You could try something like the following:
SELECT
m.Meas_name
,DAYOFWEEK(r.ProcessDate) as DayOfTheWeek
,(COUNT(CASE WHEN e.Event_Name = 'Success' tHEN e.Meas_id END)/(COUNT(e.Meas_id) * 1.0)) * 100 as PercentageSuccess
FROM
Measurements m
INNER JOIN Events e
ON m.Meas_id = e.Meas_id
INNER JOIN Readings r
ON e.Meas_id = r.Meas_id
AND e.Machine_id = r.Tool_id
AND r.Status = 'Completed'
AND r.ProcessDate BETWEEN '2016-01-01' AND '2016-01-07'
WHERE
m.Meas_name IN ('Length','Breadth')
GROUP BY
m.Meas_name
,DAYOFWEEK(r.ProcessDate)
Note this is written for mysql because that is what is tagged in you post. if you actually want sql-server as your syntax suggests let me know. Also, I am guessing that you a really want to filter by processdate but if you want to filter by Event.CreateDate then put that in the ON condition of the Events join.
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.