Reputation: 181
How to return records in forms of rate/ratio group by date using SQL server? For e.g.,:
Date PassingRate(%)
2019-01-01 50
2019-01-10 78
2019-02-03 90
The table properties are
DeviceId - string
Eventtime - long, it's timestamp
MTemperature1 - float
Mtemperature2 - float
lowdetergent - 0 or 1
lowdryer - 0 or 1
interrupted - 0 or 1
I need to select a timestamp range, for example, from 0000000000 to 9999999999. There are multiple records each day, the SQL should filter data and retrieve me processed data that meet certain standard
Below is my query clause:
SELECT CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00')) AS Date,
CONVERT(decimal(18, 2),
(SELECT COUNT(*)
FROM testTbl
WHERE lowdetergent = 0
AND lowdryer = 0
AND MTemperature1 >= 0
AND MTemperature2 >= 0
AND interrupted = 0
AND DeviceId = 'test1'
AND EventTime >= 0000000000
AND EventTime <= 9999999999) * 100.0 / (SELECT COUNT(*)
FROM testTbl
WHERE DeviceId = 'test1'
AND EventTime >= 0000000000
AND EventTime <= 9999999999)) AS PassingRate
FROM testTbl
GROUP BY CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00'))
ORDER BY Date;
The result of my query clause:
DATE PASSINGRATE
2019-01-21T00:00:00.0000000 25.00
2019-01-22T00:00:00.0000000 25.00
2019-02-12T00:00:00.0000000 25.00
As you can see, the "PassingRate" column seems to be overall rate, not daily rate.
Upvotes: 3
Views: 259
Reputation: 1269613
The simplest method might be to use avg()
:
SELECT CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00')) AS Date,
AVG(CASE WHEN lowdetergent = 0 AND lowdryer = 0 AND MTemperature1 >= 0 AND MTemperature2 >= 0 AND
interrupted = 0 AND DeviceId = 'test1' AND EventTime >= 0000000000 EventTime <= 9999999999
THEN 100.0
WHEN DeviceId = 'test1' AND EventTime >= 0000000000 AND EventTime <= 9999999999
THEN 0
END) AS PassingRate
FROM testTbl
GROUP BY CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00'))
ORDER BY Date;
This can probably be simplified to:
SELECT CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00')) AS Date,
AVG(CASE WHEN lowdetergent = 0 AND lowdryer = 0 AND MTemperature1 >= 0 AND MTemperature2 >= 0 AND interrupted = 0
THEN 100.0
ELSE 0
END) AS PassingRate
FROM testTbl
WHERE DeviceId = 'test1' AND EventTime >= 0000000000 AND EventTime <= 9999999999
GROUP BY CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00'))
ORDER BY Date;
Upvotes: 1
Reputation: 1180
If i understand your wall attempt and your excepted output i think this query can respond :
SELECT CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00')) AS Date,
CONVERT(decimal(18, 2),SUM(CASE WHEN lowdetergent = 0
AND lowdryer = 0
AND MTemperature1 >= 0
AND MTemperature2 >= 0
AND interrupted = 0
AND DeviceId = 'test1'THEN 1 ELSE 0 END) / SUM (CASE WHEN DeviceId = 'test1' THEN 1 ELSE 0 END))
FROM testTbl
GROUP BY CONVERT(date, DATEADD(S, EventTime + 8 * 3600, '1970-01-01 00:00:00'))
ORDER BY Date;
Please provide some mock (sample) data and structure off table for any other help.
Upvotes: 2
Reputation: 30555
your problem is your subquery does not relate with your main query (they are not joined). Everytime your subquery sums static time range instead of specific time related with your main query.
select
date,
( select count(*) from innerTbl where dt between '01.01.2018' and '01.01.2019') static_sum
from t
is not same with
select
mdt,
( select count(*) from innerTbl where dt = t.mdt) joined_table_sum
from t
Upvotes: 1