如何使用SQL Server返回按日期分组的比率/费率

时间:2019-02-12 08:15:58

标签: sql sql-server

如何使用SQL Server按日期按比率/比率组的形式返回记录?例如:

Date      PassingRate(%)
2019-01-01        50
2019-01-10        78
2019-02-03        90

表属性是

DeviceId       - string
Eventtime      - long, it's timestamp
MTemperature1  - float
Mtemperature2  - float
lowdetergent   - 0 or 1
lowdryer       - 0 or 1
interrupted    - 0 or 1

我需要选择一个时间戳范围,例如,从0000000000到9999999999。 每天有多条记录,SQL应该过滤数据并检索满足某些标准的经处理数据

下面是我的查询子句:

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;

我的查询子句的结果:

          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

如您所见,“ PassingRate”列似乎是总体费率,而不是每日费率。

3 个答案:

答案 0 :(得分:2)

如果我了解您的隔离墙尝试和排除的输出,我认为此查询可以响应:

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;

请提供一些模拟(样本)数据和表外结构以获取其他帮助。

答案 1 :(得分:1)

您的问题是您的子查询与您的主查询不相关(它们未联接)。每次子查询汇总静态时间范围,而不是与主查询相关的特定时间。

select 
  date, 
  ( select count(*) from innerTbl where dt between '01.01.2018' and '01.01.2019') static_sum
from t

不同
select 
  mdt, 
  ( select count(*) from innerTbl where dt = t.mdt) joined_table_sum
from t

答案 2 :(得分:1)

最简单的方法可能是使用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;

这可能可以简化为:

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;