Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PostgresQL:需要语句帮助_Sql_Postgresql - Fatal编程技术网

PostgresQL:需要语句帮助

PostgresQL:需要语句帮助,sql,postgresql,Sql,Postgresql,考虑一个具有以下PostgresQL数据库表结构的表(为了演示,在这里进行了精简): 随着时间的推移,表格中会出现许多事件。现在,我们需要一个用于报告的SQL statement,它按时间(例如每小时)聚合值,并对特定类型的值进行平均和计数。因此,报告如下所示: [example report for type="standard"] Time Count Avg 00:00 30 20 01:00 12 24 02:00 9 19

考虑一个具有以下PostgresQL数据库表结构的表(为了演示,在这里进行了精简):

随着时间的推移,表格中会出现许多事件。现在,我们需要一个用于报告的SQL statement,它按时间(例如每小时)聚合值,并对特定类型的值进行平均和计数。因此,报告如下所示:

[example report for type="standard"]  
Time    Count   Avg   
00:00   30      20
01:00   12      24
02:00   9       19
...
在此之前,这是非常直截了当的,因此上述报告的声明如下:

select extract(hour from time) time, count(1), avg(value)
from reportdata
where type = 'standard'
group by time;
现在是棘手的部分-我需要显示每种类型的报告,其中包含所有类型的总数以及每个时间段中与特定类型相关的百分比。 为此,我需要一个语句,它为每个时间帧和每个可能的类型(可以从包含所有可能类型的单独表中选择)生成一行,然后代码可以从中提取每个类型的报告选项卡,而无需再次从数据库请求。 因此,结果应该是这样的(请注意,在没有找到类型值的时间范围内的“空”行):

这句话是怎么产生的?

类似这样的话

select extract(hour from rd.time) time, 
       at.type,
       count(at.value) over (partition by extract(hour from time)) as total,
       count(at.value) over (partition by rd.type) as count,
       avg(value) over (partition by rd.type) as avg,
from all_types at 
  left join reportdata rd on at.type = rd.type
group by time, at.type;
all_type
是“包含所有可能类型的单独表格”)

我在时间戳上使用了
date\u trunc
,因为我认为你想要的是将每天的每一小时分开。如果你真的想把一天中的每一个小时加起来,只需返回到你的
摘录

更新以匹配注释中的新要求:
这正是我所需要的——非常感谢!但还有一个问题:如果在一个时间范围内没有价值,那么就没有价值线。是否可以轻松地在每个时间范围内(当然是在给定的“从”和“到”中的“到”部分)生成这些内容?这很完美,再一次:非常感谢!如果我可以的话,我会给你超过1票。。。
[example report for all types assuming there are 3 possible types]  
Time    Type       Total   Count   Percent   Avg   
00:00   standard   40      30      0.75      20
00:00   special    40      10      0.25      8
00:00   super      40      0       0         0
01:00   standard   12      12      1.0       24
01:00   special    12      0       0         0
01:00   super      12      0       0         0
02:00   standard   9       3       0.33      20
02:00   special    9       0       0         0
02:00   super      9       6       0.67      15
...
select extract(hour from rd.time) time, 
       at.type,
       count(at.value) over (partition by extract(hour from time)) as total,
       count(at.value) over (partition by rd.type) as count,
       avg(value) over (partition by rd.type) as avg,
from all_types at 
  left join reportdata rd on at.type = rd.type
group by time, at.type;
select 
    s.hour as "Time", 
    s.type as "Type", 
    s.total as "Total", 
    coalesce(r.total, 0) as "Count", 
    round(coalesce(r.total, 0) * 1.0/s.total, 2) as "Percent", 
    round(coalesce(r.avg, 0), 2) as "Avg"
from (
    select 
        date_trunc('hour', time) as hour, 
        type, 
        count(*) as total, 
        avg(value) as avg
    from reportdata
    group by hour, type
    ) r
right outer join (
    select 
        date_trunc('hour', time) as hour,
        t.type,
        count(*) as total
    from reportdata
    inner join type t on true
    group by hour, t.type
    ) s on s.hour = r.hour and s.type = r.type
order by s.hour, s.type
;
        Time         |   Type   | Total | Count | Percent |  Avg  
---------------------+----------+-------+-------+---------+-------
 2012-04-02 00:00:00 | special  |    40 |    10 |    0.25 |  8.00
 2012-04-02 00:00:00 | standard |    40 |    30 |    0.75 | 20.00
 2012-04-02 00:00:00 | super    |    40 |     0 |    0.00 |  0.00
 2012-04-02 01:00:00 | special  |    12 |     0 |    0.00 |  0.00
 2012-04-02 01:00:00 | standard |    12 |    12 |    1.00 | 24.00
 2012-04-02 01:00:00 | super    |    12 |     0 |    0.00 |  0.00
 2012-04-02 02:00:00 | special  |     9 |     0 |    0.00 |  0.00
 2012-04-02 02:00:00 | standard |     9 |     3 |    0.33 | 20.00
 2012-04-02 02:00:00 | super    |     9 |     6 |    0.67 | 15.00
(9 rows)
select 
    s.hour as "Time", 
    s.type as "Type", 
    s.total as "Total", 
    coalesce(r.total, 0) as "Count", 
    case s.total when 0 then round(0, 2) else
        round(coalesce(r.total, 0) * 1.0/s.total, 2)
        end as "Percent", 
    round(coalesce(r.avg, 0), 2) as "Avg"
from (
    select 
        date_trunc('hour', time) as hour, 
        type, 
        count(*) as total, 
        avg(value) as avg
    from reportdata
    group by hour, type
) r
right outer join (
    select 
        date_trunc('hour', d) as hour,
        t.type,
        count(r.time) as total
    from reportdata r
    right outer join (
        select d 
        from generate_series(
            (select min(time) from reportdata),
            (select max(time) from reportdata),
            '1 hour'
        ) g(d)
    ) g on date_trunc('hour', g.d) = date_trunc('hour', r.time)
    inner join type t on true
    group by hour, t.type
) s on s.hour = r.hour and s.type = r.type
order by s.hour, s.type
;
        Time         |   Type   | Total | Count | Percent |  Avg  
---------------------+----------+-------+-------+---------+-------
 2012-04-01 22:00:00 | special  |     1 |     0 |    0.00 |  0.00
 2012-04-01 22:00:00 | standard |     1 |     1 |    1.00 | 10.00
 2012-04-01 22:00:00 | super    |     1 |     0 |    0.00 |  0.00
 2012-04-01 23:00:00 | special  |     0 |     0 |    0.00 |  0.00
 2012-04-01 23:00:00 | standard |     0 |     0 |    0.00 |  0.00
 2012-04-01 23:00:00 | super    |     0 |     0 |    0.00 |  0.00
 2012-04-02 00:00:00 | special  |    40 |    10 |    0.25 |  8.00
 2012-04-02 00:00:00 | standard |    40 |    30 |    0.75 | 20.00
 2012-04-02 00:00:00 | super    |    40 |     0 |    0.00 |  0.00
 2012-04-02 01:00:00 | special  |    12 |     0 |    0.00 |  0.00
 2012-04-02 01:00:00 | standard |    12 |    12 |    1.00 | 24.00
 2012-04-02 01:00:00 | super    |    12 |     0 |    0.00 |  0.00
 2012-04-02 02:00:00 | special  |     9 |     0 |    0.00 |  0.00
 2012-04-02 02:00:00 | standard |     9 |     3 |    0.33 | 20.00
 2012-04-02 02:00:00 | super    |     9 |     6 |    0.67 | 15.00
 2012-04-02 03:00:00 | special  |     0 |     0 |    0.00 |  0.00
 2012-04-02 03:00:00 | standard |     0 |     0 |    0.00 |  0.00
 2012-04-02 03:00:00 | super    |     0 |     0 |    0.00 |  0.00
 2012-04-02 04:00:00 | special  |     1 |     0 |    0.00 |  0.00
 2012-04-02 04:00:00 | standard |     1 |     1 |    1.00 | 10.00
 2012-04-02 04:00:00 | super    |     1 |     0 |    0.00 |  0.00
(21 rows)