Grafana mysql query - mysql

Please suggest the MySQL queries for grafana.
I have data with I required MTTR from data, I'm getting expected output with add "15" as an integer in the query but not with count queries.
from "[with integer][1]" image.
sum(seconds_to_resolve) / 15 /60 as "MTTR" ---> value is 25.4
Getting different value if mentioned
from "[with count Function][2]" image.
sum(seconds_to_resolve) / count(seconds_to_resolve) / 60 as "MTTR" ---> value is 322
query:
SELECT
$__timeGroupAlias(created_on,$__interval),
sum(seconds_to_first_ack) AS "seconds_to_first_ack",
sum(seconds_to_resolve) AS "seconds_to_first_resolve",
count(seconds_to_resolve) AS "COUNT",
sum(seconds_to_resolve) / count(seconds_to_resolve) /60 as "MTTR"
FROM alerts_report
WHERE
$__timeFilter(created_on) AND
service_name = 'RKSOL'
GROUP BY 1
ORDER BY $__timeGroup(created_on,$__interval)
[with integer]
[with count Function]

I would use average function to calculate MTTR (mean time to resolution):
SELECT
$__timeGroupAlias(created_on,$__interval),
sum(seconds_to_first_ack) AS "seconds_to_first_ack",
sum(seconds_to_resolve) AS "seconds_to_first_resolve",
count(seconds_to_resolve) AS "COUNT",
avg(seconds_to_resolve) AS "MTTR"
FROM alerts_report
WHERE
$__timeFilter(created_on) AND
service_name = 'RKSOL'
GROUP BY 1
ORDER BY $__timeGroup(created_on,$__interval)

Related

Calculate sum when value changes

I am trying to build a system that will track vehicle fuelings, and have run into a problem with one report; determining fuel efficiency in distance/fuel. Sample data is:
odometer
fuel
partial_fillup
61290
10.3370
0
61542
6.4300
0
61735
4.3600
0
61994
7.5000
0
62242
5.4070
0
62452
8.1100
0
62713
5.7410
1
62876
9.4850
0
63243
6.1370
1
63499
10.7660
0
Where odometer is the total distance the vehicle has traveled, fuel is the number of gallons or liters put in, and partial_fillup is a boolean meaning the fuel tank was not completely filled if non-zero.
If the user fills the tank each time the query I can use is:
set #a = null;
select
odometer,
odometer-previousOdometer distance,
fuel,
(odometer-previousOdometer)/fuel mpg,
partial_fillup
from
(
select
#a as previousOdometer,
#a:=odometer,
odometer,
fuel/1000 fuel,
partial_fillup
from fuel
where
vehicle_id =1
and odometer >= 61290
order by odometer
) as readings
where readings.previousOdometer is not null;
However, when the user only partially fills the tank, the correct procedure would be to subtract the last full fueling from current odometer reading, then divide by the sum of all fuel since the previous odometer reading, so at odometer 63499, the calculate would be (63499-62876)/(10.7660+6.1370)
This will get the average used on the last ride:
select
odometer,
odometer-lag(odometer) over (order by odometer) as distance,
fuel,
(odometer-lag(odometer) over (order by odometer))/fuel as mpg
from fuel
output:
odometer
distance
fuel
mpg
61290
10.3370
61542
252
6.4300
39.1913
61735
193
4.3600
44.2661
61994
259
7.5000
34.5333
62242
248
5.4070
45.8665
62452
210
8.1100
25.8940
62713
261
5.7410
45.4625
62876
163
9.4850
17.1850
63243
367
6.1370
59.8012
63499
256
10.7660
23.7786
Or you can calculate the total drive distance, and the total amount of fuel used:
select
distance,
sum_fuel,
distance/sum_fuel as mpg
from (
select
f.odometer,
f.odometer-(select min(odometer) from fuel) as distance,
fuel,
sum_fuel
from fuel f
inner join (
select
odometer,
sum(fuel) over (order by R) as sum_fuel
from (
select
odometer,
fuel,
row_number() over (order by odometer) R
from fuel) x
) x on x.odometer = f.odometer
) x2
which will get next output, which will get closer to an average after a longer time of measurement:
distance
sum_fuel
mpg
0
10.3370
0.0000
252
16.7670
15.0295
445
21.1270
21.0631
704
28.6270
24.5922
952
34.0340
27.9720
1162
42.1440
27.5721
1423
47.8850
29.7170
1586
57.3700
27.6451
1953
63.5070
30.7525
2209
74.2730
29.7416
DBFIDDLE
I was able to figure it out after studying Luuk's answer. I'm sure there is a more efficient way to do this; I am not used to using variables in SQL. But, the answers are correct in the test data.
set #oldOdometer = null;
set #totalFuel = 0;
select
s.odometer,
format(fuel, 3) fuel,
s.distance,
format( distance / fuel, 2) as mpg
from (
select
partial_fillup as partial,
odometer,
(fuel+#totalFuel) as fuel,
#totalFuel as totalFuel,
#oldOdometer oldOdometer,
if ( partial_fillup, null,odometer - #oldOdometer ) as distance,
#totalFuel := if ( partial_fillup, #totalFuel + fuel, 0) as pastFuel,
#oldOdometer := if (partial_fillup,#oldOdometer,odometer ) as runningOdometer
from
fuel
order by
odometer ) s
where s.distance is not null
order by s.odometer
limit 1,999;
limit 1,999 simply there to skip the first row returned, since there is not enough data to calculate distance or mpg. On my copy of MySQL, doing this means you do not need to initialize the two variables (you don't have to include the set commands at the beginning), so it works with my reporting tool very well. If you do initialize them, you do not need the limit statement. Works assuming you don't have more than 999 rows returned.

Mysql SUM() TIME wrong format

I'm calculating the sum of two columns from the same table with SUM() but the end result is an integer (286676). I'm guessing it's milliseconds? How can I convert to TIME(00:00:00)?
database
id|hours_worked | hours_worked_wk2 |
hours_worked = 14:33:38
hours_worked_wk2 = 14:33:38
Query
SELECT *,SEC_TO_TIME(SUM(TIME_TO_SEC(ep.hours_worked)))+SEC_TO_TIME(SUM(TIME_TO_SEC(ep.hours_worked_wk2)))
AS TotalHoursWorked
FROM employeepayroll ep
JOIN employees em ON ep.employee_id=em.employee_id
JOIN payroll p ON ep.payroll_id=p.payroll_id
JOIN payrolltaxes pt ON ep.payroll_id=pt.payroll_id
WHERE ep.timesheet_status='Approved' AND p.pay_group='26'
ORDER BY ep.payroll_id DESC
TotalHoursWorkd = 286676
Use the following formula.
hours = cast(duration_in_milliseconds \ (60 * 60 * 1000) as int)
mins = (duration_in_milliseconds \ (60 * 1000)) mod 60
secs = (duration_in_milliseconds \ 1000) mod 60
Your query will look something like this:
select cast(duration_in_milliseconds\(60*60*1000) as int)+':'((duration_in_milliseconds \ (60*1000)) mod 60;)+':'((duration_in_milliseconds \ 1000) mod 60) from something
When you see it...
14:33:38 >>> 143,338 × 2 = 286,676
Yikes. The numbers in the times are being implicitly cast to integers.
You are adding the two values of SEC_TO_TIME(SUM(...))+SEC_TO_TIME(SUM(...)).
Instead, use SEC_TO_TIME(SUM(...) + SUM(...)).

How to write a MySQL statement with multiple conditionals?

I have the following table:
id (integer, primary key)
amount_low (integer)
amount_high (integer)
fixedprice (decimal 4,2 Null)
percentadjust (decimal 4,2 Null)
itemname (varchar 50)
A record will have a value in either the "fixedprice" or "percentadjust" field, but not both. One will be NULL, and the other will have a value.
I need to get records based on a single input amount, "X":
If the "fixedprice" field has a value, I need to get the record if X is >= (fixedprice * amount_low) AND X is <= (fixedprice * amount_high).
If the "percentadjust" field has a value, I need to get the record if X is >= ((((percentadjust / 100) + 1) * 3.5) * amount_low) AND X is <= ((((percentadjust / 100) + 1) * 3.5) * amount_high).
The "3.5" is a value that changes on occasion and I'm not too concerned about that part.
What is a good way to do this in MySQL?
Sample data: (also see http://sqlfiddle.com/#!9/922a0 )
id amount_low amount_high fixedprice percentadjust itemname
-----------------------------------------------------------------
1 20 25 2.25 NULL A
2 50 75 2.38 NULL B
3 23 32 NULL 9.75 C
4 14 22 NULL 9.12 D
5 96 112 2.58 NULL E
Assuming your X was entered as 111 it would be
select * from tblItems
where (fixedprice is not null and 111>=(fixedprice * amount_low) and 111 <= (fixedprice * amount_high) )
OR (percentadjust is not null and 111>=((((percentadjust / 100) + 1) * 3.5) * amount_low) AND 111<=((((percentadjust / 100) + 1) * 3.5) * amount_high))
Note you can always write it as where xyz between A and B to simplify somethings slightly.
Remember that a lot of time can be wasted debugging logic operators when AND and OR are used and safe wrappers with parentheses are not used. So, if you intermingle AND with OR, wrap things well.

What way to "rank" dataset Mysql

Situation is as follows:
I have a database with 40.000 cities. Those cities have certain types of properties with an value.
For example "mountains" or "beaches". If a city has lots of mountains the value for mountain will be high if there are less mountains the number is lower.
Table with city name and properties and values:
With that, I have a table with the avarage values of all those properties.
What I need to happen: I want the user search for a city with has one or multiple properties, find the best match and attach a score from 0 - 100 to it.
The way I do this is as follow:
1. I first get the 25%, 50% and 70% values for the properties:
_var_[property]_25 = [integer]
_var_[property]_50 = [integer]
_var_[property]_70 = [integer]
2. Then I need to use this algorithm:
_var_user_search_for_properties = [mountain,beach]
_var_max_property_percentage = 100 / [properties user search for]
_var_match_percentage = 0
for each _var_user_search_for_properties
if [property] < _var_[property]_25 then
_var_match_percentage += _var_max_property_percentage
elseif [property] < _var_[property]_50 then
_var_match_percentage += _var_max_property_percentage / 4 * 3
elseif [property] < _var_[property]_75 then
_var_match_percentage += _var_max_property_percentage / 4 * 2
elseif [property] < 0 then
_var_match_percentage += _var_max_property_percentage / 4 * 1
end if
next
order all rows by _var_match_percentage desc
The question is: is it posible to do this with MySQL?
How do I calculate this "match percentage" with it?
Or wil it be faster to get all the rows and indexes out of the database and loop them all trough .NET?
If the percentages can be stored in the database, you could try MySQL's LIMIT clause. See http://www.mysqltutorial.org/mysql-limit.aspx.

Why is this IIF function giving an #Error?

One of my tables has a field named Cost and a field named Extra Cost. To come up with the Total Cost, I add them together with the following field, which works just fine:
Total Cost: (Val(nz([Cost],"")))/100 + (Val(nz([Extra Cost],"")))/100
(I divide by 100 because Cost and Extra Cost are stored without a decimal point)
Now it's possible that a record will have Cost = 0, and Extra Cost > 0. But if Cost = 0, I want Total Cost to also = 0. I came up with the following, but it results in #Error if Cost = 0. It works fine if Cost > 0:
Total Cost: IIf([Cost]>0,((Val(nz([Cost],"")))/100+(Val(nz([Extra Cost],""))))/100,0)
Basically I'm looking for:
If Cost = 0, Then Total Cost = 0
Else
If Cost > 0, Then Total Cost = Cost + Extra Cost
What is wrong with the 'true' portion?
Here's a few examples of the data:
Cost Extra Cost
100 2.5
250 1.5
150 2.5
null 2.75
Based on your description, I think you can divide by 100 after you add the 2 values instead of dividing each of them by 100 before you add them. That shouldn't affect the logic, but should give you a simpler IIf expression ... which will hopefully be easier to diagnose.
IIf
(
Val(Nz([Cost], "0")) > 0,
(Val([Cost]) + Val(Nz([Extra Cost], "0"))) / 100,
0
)
Using your sample data in Access 2007, I get this result set from the following query:
Cost Extra Cost Total Cost
100 2.5 1.025
250 1.5 2.515
150 2.5 1.525
2.75 0
SELECT
y.Cost,
y.[Extra Cost],
IIf
(
Val(Nz([Cost], "0")) > 0,
(Val([Cost]) + Val(Nz([Extra Cost], "0"))) / 100,
0
) AS [Total Cost]
FROM YourTable AS y;
If the issue is that [Total Cost] requires a text value, you can use CStr() to cast the IIf numerical value to string.
CStr(
IIf
(
Val(Nz([Cost], "0")) > 0,
(Val([Cost]) + Val(Nz([Extra Cost], "0"))) / 100,
0
)
)