Simple precision issue with mysql list of numbers do not calculate the same with sum as a single calculation. (How does one handle this senario?) There is a one(1) cent difference?
Sample of rows:
Select qty, (qty*21.25)
6.5 | 138.125
0.5 | 10.625
0.5 | 10.625
0.25 | 5.3125
1 | 21.25
2 | 42.5
1 | 21.25
2 | 42.5
2.5 | 53.125
2.5 | 53.125
2 | 42.5
3 | 63.75
3 | 63.75
3.5 | 74.375
Sample 2:
Select sum(qty), sum(amount)
30.25 | 642.8175
Sample 3:
Select 30.25*21.25
642.8125
Since the answer was so vague. Let try this. Can anyone explain why the mysql statement produces the wrong results.
SELECT 6.875+3.125
10.00
Shouldn't this be
10.01
Read this article. Floating point numbers are not stored as exact values, therefore could be problems with calculation precision
Related
I am facing sorting issue in mysql
See the output of below query:
select astrologers.id,astrologers.name,chat_online,online,experience from `astrologers`
where `astrologers`.`status` = '1'
order by experience asc limit 10;
id
name
chat_online
online
experience
15
Astro Anoop
0
0
3
20
Test Astro2
0
0
3
3
Test anoop
0
0
5
4
Anoop Kumar trivedi
0
0
5
7
Test
0
0
5
58
Neeraj yadav
1
0
5
45
Satish Kumar Gupta
1
1
10
56
AP Sharma
1
0
15
40
VG Astrologer App
1
0
55
In above result id 58 (Neeraj yadav) is at 6th position but when I run the same query with limit 3, same id 58 (Neeraj yadav) is at 3rd position:
select astrologers.id,astrologers.name,chat_online,online,experience
from `astrologers`
where `astrologers`.`status` = '1'
order by experience asc limit 3;
id
name
chat_online
online
experience
20
Test Astro2
0
0
3
15
Astro Anoop
0
0
3
58
Neeraj yadav
1
0
5
The 3rd row in above result should be id 3 (Test anoop) but it gives id 58 (Neeraj yadav)
Is this bug in mysql?
Is this a bug in MySQL?
No. The problem is that your sort is not deterministic, and gives ties in the third position:
| 3 | Test anoop | 0 | 0 | 5 |
| 4 | Anoop Kumar trivedi | 0 | 0 | 5 |
| 7 | Test | 0 | 0 | 5 |
| 58 | Neeraj yadav | 1 | 0 | 5 |
All 4 users have the same experience, hence leaving the database to figure out how they should be sorted.
When asked to return to top 3 rows, the database picks the first two, and then one of the 4 ties. The result that you get might not be consistent over consequent executions of the same query, as you are starting to see.
Bottom line: know you data; if you want a deterministic result, then use a deterministic sort. We could, for example, use id to break the ties, hence making the result predictable:
order by experience, id limit 3
I have this query to extract total_hours, start_date and end_date:
select proj.start_date, proj.end_date, sum(ifnull(work.hours_estimate,0)) as total_hours
from project_table proj
left outer join project_task work on
work.project_id = proj.id
where proj.id = 3
This query gives me a single row of result:
start_date | end_date | total_hour
----------------------------------------
2017-04-24 | 2017-05-15 | 119
What I want is to generate a daily interval of rows, constantly decreasing the total_hours by a certain amount, say 19 hours, and the day increasing by 1 day.
Expected results:
day | hours_left
------------------------
2017-04-24 | 119
2017-04-25 | 100
2017-04-26 | 81
2017-04-27 | 62
2017-04-28 | 43
2017-04-29 | 24
... and so on and so forth until it reaches 2017-05-15 (of course, no negative for hours_left, just zero if negative)
can't seem to figure out how to do this.
QUESTIONS:
1.) Is this possible in MySQL?
2.) If this is possible in MySQL, is it efficient/convinient?
If not, I could just do it in application, as state in the comments
I am trying to query out only the root_cause that is more than 72 hours and when it find 72 hours or more it will add up.. For example
I have root cause A = 78 hours and Root cause B = 100 hours since these two is more than 72 it should add up 178 hours as "MNPT". Anything that is less than 72 add up and make up routine NPT
I am using derived table query out but the outcome still display the hours including those that less than 72
Select operation_uid, sum (npt_duration) as mnpt from fact_npt_root_cause where npt_duration>72 group by root_cause_code having sum (npt_duration)>72
See this table
|ROOT CAUSE CODE | NPT Duration |
| | |
|A | 23 |
|B | 78 |
|C | 45 |
|D | 100 |
|E | 90 |
When the root cause value is more than 72 hours => then add up those value for example
root cause code B, D, E = 78 + 100 + 90 = 268 as MNPT
When the root cause value is less than 72 hours => then add up the value as 23 + 45 = 68 as routine NPT
I'm not sure of what you want to do but querying operation_uid and grouping by root_cause_code assumes that you always has the same operation_uid for a given root_cause_code... Don't you rather mean :
SELECT operation_uid,
sum (npt_duration) as mnpt
FROM fact_npt_root_cause
WHERE npt_duration>72
GROUP by operation_uid, root_cause_code
HAVING SUM (npt_duration)>72;
I have table something like this (there's also "device_id" and "timestamp" columns)
day | interval | value
----------------------------
1 | 14 | 63 // start of a day
1 | 14 | 83
1 | 14 | 73
1 | 15 | 23
1 | 15 | 33
1 | 15 | 50
2 | 16 | 23 // start of a day
2 | 16 | 33
2 | 16 | 50
I want to select all intervals in a day. That is simple.
However, an interval can start a bit before a day flips, or end a bit past:
day | interval | value
----------------------------
7 | 14 | 63
7 | 14 | 83
8 | 14 | 73 // start of a day
8 | 15 | 23
8 | 15 | 33
8 | 15 | 50
8 | 16 | 23
8 | 16 | 33
9 | 16 | 50 // start of a day
Now I'd like to select all three intervals - or even better intervals that are mostly in that day.
SELECT ... WHERE day = 8
Gives me only parts of the start/end intervals (14, 16). That's useless, I need the complete intervals.
If there's no solution, I'll just do three queries, but there might be some SQL trick I'm not aware of?
It's MySQL, called from PHP.
More visually:
day 7 | day 8 | day 9
------------------+-------------------+---------------
###13### ###14### ###15### ###16### ###17###
... 63 83 73 23 33 50 23 33 50 ...
I want all values in day 8 -> intervals 14, 15, 16
I think you are looking for this:
SELECT * FROM intervals
WHERE interval IN (
SELECT DISTINCT interval FROM intervals WHERE day = 8)
This selects all interval data where at least one of the entries for that interval occurs in day 8. The subquery determines which unique intervals happen in the day, which is then used by the outer query to select their specifics.
SELECT DISTINCT y.*
FROM my_table x
JOIN my_table y
ON y.some_column = x.some_column
WHERE x.some_other_column = 8;
I would like to use highcharts to see the temperature behaviour on last hour.
I record 20 to 30 temperature values for each hour.
Here, I would like to extract, for last hour, 4 to 6 average values (one value for a 10 or 15 minutes period) and plot them. Maybe I will change that to 3 values (one for 20 minutes) to get something smoother.
I have values like that (for example) :
mysql> SELECT date,valeur FROM temperature
+---------------------+--------+
| date | valeur |
+---------------------+--------+
| 2013-09-26 11:30:40 | 25.2 |
| 2013-09-26 11:33:19 | 25.4 |
| 2013-09-26 11:34:12 | 25.5 |
| 2013-09-26 11:38:37 | 25.4 |
| 2013-09-26 11:39:30 | 25.4 |
| 2013-09-26 11:40:23 | 25.4 |
| 2013-09-26 11:43:02 | 25.4 |
| 2013-09-26 11:45:41 | 25.3 |
| 2013-09-26 11:47:33 | 25.3 |
| 2013-09-26 11:51:07 | 25.4 |
| 2013-09-26 11:51:52 | 25.3 |
...
I tried to extract with this command :
SELECT ROUND(UNIX_TIMESTAMP(date)/(15 * 60)) AS timekey, ROUND(AVG(valeur),1) AS a FROM temperature WHERE date >= (now() - INTERVAL 1 HOUR) GROUP BY timekey ORDER BY DATE;
But I don't get any output. If I change the interval to 5 hours, I get 16 values :
[1534861, 24.600000]
[1534862, 24.600000]
[1534863, 24.600000]
[1534864, 24.700000]
[1534865, 24.700000]
[1534866, 24.600000]
[1534867, 24.600000]
[1534868, 24.600000]
[1534869, 24.600000]
[1534870, 24.600000]
[1534871, 24.700000]
[1534872, 24.700000]
[1534873, 24.700000]
[1534874, 24.800000]
[1534875, 25.000000]
[1534876, 25.200000]
Any idea how to correct this mysql request ?
Thanks you all
Greg
edit - See selected answer : the code was good, but the timezone wasn't !
I am guessing your issue is most likely a timezone difference of 1 hour.
if you get no values for last hour but you get 16 for last 5(making up 4 hours worth of values), that sounds like you have no values for last hour. If you are certain you do, check the timezone of data vs timezone of now()
try using sysdate perhaps. Quote from manual:
In addition, the SET TIMESTAMP statement affects the value returned by
NOW() but not by SYSDATE(). This means that timestamp settings in the
binary log have no effect on invocations of SYSDATE(). Setting the
timestamp to a nonzero value causes each subsequent invocation of
NOW() to return that value. Setting the timestamp to zero cancels this
effect so that NOW() once again returns the current date and time.
See the description for SYSDATE() for additional information about the
differences between the two functions.
This should work (note floor() usage):
SELECT from_unixtime(floor(unix_timestamp(date) / 15 * 60) * 15 * 60) AS tstamp,
round(avg(valeur),1) AS a
FROM temperature
WHERE date >= (now() - INTERVAL 1 HOUR)
GROUP BY 1
ORDER BY 1