Sql 按时间统计和删除数据

Sql 按时间统计和删除数据,sql,sqlite,group-by,union,Sql,Sqlite,Group By,Union,我正在寻找一个简单易读的智能SQL查询SQLite引擎,用于处理列中的数据。用一个例子更容易解释: 数据表: id elapsedtime httpcode 1 0.0 200 2 0.1 200 3 0.3 301 4 0.6 404 5 1.0 200 6 1.1 404 7 1.2

我正在寻找一个简单易读的智能SQL查询SQLite引擎,用于处理列中的数据。用一个例子更容易解释:

数据表:

 id  elapsedtime httpcode
 1          0.0      200
 2          0.1      200
 3          0.3      301
 4          0.6      404
 5          1.0      200
 6          1.1      404
 7          1.2      500
预期结果集:按httpcode显示的列,按时间显示的代码数。在本例中,时间衰减为0.2s,但可以在1秒或10s内衰减。我只对一些预期的http_代码感兴趣:

 time code_200 code_404 code_500 code_other
 0.0        2        0        0          0
 0.2        0        0        0          1
 0.4        0        1        0          0
 0.6        0        0        0          0
 0.8        0        0        0          0
 1.0        1        1        1          0
时间不一定是连续的。在上一个示例中,可以删除时间为0.6和0.6的线

目前,我可以通过http代码执行4个不同的请求,然后在开发的应用程序中放弃结果:

select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_200
from test
where (httpcode=200)
group by time
但我很确定我可以通过一个查询实现这一点。不幸的是,我没有掌握UNION关键字

有没有一种方法可以在一次选择中获得这样的数据


请参阅SQLFiddle:

找到了一个比我原来的帖子更好的解决方案,如果您好奇的话,我会把它放在后面。以下是更好的解决方案:

with t1 as (
    select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,
    case httpcode when 200 then 1 else 0 end code_200,
    case httpcode when 404 then 1 else 0 end code_404,
    case httpcode when 500 then 1 else 0 end code_500,
    case when httpcode not in (200, 404, 500) then 1 else 0 end code_other
    from test
)

select time,
sum(code_200) as count_200,
sum(code_404) as count_404,
sum(code_500) as count_500,
sum(code_other) as count_other
from t1
group by time;
旧的解决方案:

with t1 as (
    select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,
    case httpcode when 200 then 1 else 0 end code_200,
    case httpcode when 404 then 1 else 0 end code_404,
    case httpcode when 500 then 1 else 0 end code_500,
    case when httpcode not in (200, 404, 500) then 1 else 0 end code_other
    from test
)

select time,
sum(code_200) as count_200,
sum(code_404) as count_404,
sum(code_500) as count_500,
sum(code_other) as count_other
from t1
group by time;
这看起来可能不太容易,但它或多或少起作用,只是您所需的输出和我得到的结果之间的区别是,在您的示例中,没有值0.6和0.8的时间分组被忽略:

with 

t_all as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as total
from test
group by time
),

t_200 as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_200
from test
where (httpcode=200)
group by time),

t_404 as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_404
from test
where (httpcode=404)
group by time),

t_500 as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_500
from test
where (httpcode=500)
group by time),

t_other as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_other
from test
where (httpcode not in (200, 404, 500))
group by time)

select 
t_all.time,
total,
ifnull(code_200,0) as count_200,
ifnull(code_404,0) as count_404,
ifnull(code_500,0) as count_500,
ifnull(code_other,0) as count_other
from t_all
left join t_200 on t_all.time = t_200.time
left join t_404 on t_all.time = t_404.time
left join t_500 on t_all.time = t_500.time
left join t_other on t_all.time = t_other.time;

找到了一个比我原来的帖子更好的解决方案,如果你好奇的话,我会把它留在里面。以下是更好的解决方案:

with t1 as (
    select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,
    case httpcode when 200 then 1 else 0 end code_200,
    case httpcode when 404 then 1 else 0 end code_404,
    case httpcode when 500 then 1 else 0 end code_500,
    case when httpcode not in (200, 404, 500) then 1 else 0 end code_other
    from test
)

select time,
sum(code_200) as count_200,
sum(code_404) as count_404,
sum(code_500) as count_500,
sum(code_other) as count_other
from t1
group by time;
旧的解决方案:

with t1 as (
    select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,
    case httpcode when 200 then 1 else 0 end code_200,
    case httpcode when 404 then 1 else 0 end code_404,
    case httpcode when 500 then 1 else 0 end code_500,
    case when httpcode not in (200, 404, 500) then 1 else 0 end code_other
    from test
)

select time,
sum(code_200) as count_200,
sum(code_404) as count_404,
sum(code_500) as count_500,
sum(code_other) as count_other
from t1
group by time;
这看起来可能不太容易,但它或多或少起作用,只是您所需的输出和我得到的结果之间的区别是,在您的示例中,没有值0.6和0.8的时间分组被忽略:

with 

t_all as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as total
from test
group by time
),

t_200 as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_200
from test
where (httpcode=200)
group by time),

t_404 as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_404
from test
where (httpcode=404)
group by time),

t_500 as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_500
from test
where (httpcode=500)
group by time),

t_other as (select
0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_other
from test
where (httpcode not in (200, 404, 500))
group by time)

select 
t_all.time,
total,
ifnull(code_200,0) as count_200,
ifnull(code_404,0) as count_404,
ifnull(code_500,0) as count_500,
ifnull(code_other,0) as count_other
from t_all
left join t_200 on t_all.time = t_200.time
left join t_404 on t_all.time = t_404.time
left join t_500 on t_all.time = t_500.time
left join t_other on t_all.time = t_other.time;
这可能对你有帮助

select
    0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_200,
    0 as code_404,
    0 as code_500,
    0 as code_other
from
    test
where (httpcode=200)
group by time
union
select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,0 as code_200,
    count(id) as code_404,
    0 as code_500,
    0 as code_other
from
    test
where (httpcode=404)
group by time
union
select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,0 as code_200,
    0 as code_400,
    count(id) as code_500,
    0 as code_other
from
    test
where (httpcode=500)
group by time
union
select
     0.2 * cast (elapsedtime/ 0.2 as int) as time,0 as code_200,
     0 as code_400,
     0 as code_500,
     count(id) as code_other
from
  test
where (httpcode<>200 and httpcode <> 404 and httpcode <> 500)
group by time
这可能对你有帮助

select
    0.2 * cast (elapsedtime/ 0.2 as int) as time, count(id) as code_200,
    0 as code_404,
    0 as code_500,
    0 as code_other
from
    test
where (httpcode=200)
group by time
union
select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,0 as code_200,
    count(id) as code_404,
    0 as code_500,
    0 as code_other
from
    test
where (httpcode=404)
group by time
union
select
    0.2 * cast (elapsedtime/ 0.2 as int) as time,0 as code_200,
    0 as code_400,
    count(id) as code_500,
    0 as code_other
from
    test
where (httpcode=500)
group by time
union
select
     0.2 * cast (elapsedtime/ 0.2 as int) as time,0 as code_200,
     0 as code_400,
     0 as code_500,
     count(id) as code_other
from
  test
where (httpcode<>200 and httpcode <> 404 and httpcode <> 500)
group by time

谢谢你的回答。我上一次尝试的结果是这样一个查询,可读性很好。我也喜欢小得多的锡炉。谢谢你的回答。我上一次尝试的结果是这样一个查询,可读性很好。我也喜欢那家小得多的餐厅谢谢。我喜欢更好的解决方案。我将测试它,并将其与具有10K行输入集的user3551009的答案进行比较。with语句可以通过将查询包含在FROM语句中来替换。是的,在这里使用公共表表达式而不是子查询只是个人偏好,我没有测试是否有任何性能差异。谢谢。我喜欢更好的解决方案。我将测试它,并将其与具有10K行输入集的user3551009的答案进行比较。with语句可以通过将查询包含在FROM语句中来替换。是的,在这里使用公共表表达式而不是子查询只是个人偏好,但我没有测试是否存在任何性能差异。