3

在我之前的问题中有一个相当大的错误

从多行中选择最早的日期

horse_with_no_name 的答案返回了一个完美的结果,我非常感激,但是我最初的问题是错误的,所以我真的很抱歉;如果你看下表;

电路_uid |客户名称|机架位置|阅读日期| 阅读时间 | 安培| 伏特 | 千瓦| 千瓦时 | 千瓦 | pf | 钥匙
-------------------------------------------------- -------------------------------------------------- ----------------------------------
cu1.cb1.r1 | 客户 1 | 12.01.a1 | 2012-01-02 | 00:01:01 | 4.51 | 229.32 | 1.03 | 87 | 1.03 | 0.85 | 15
cu1.cb1.r1 | 客户 1 | 12.01.a1 | 2012-01-02 | 01:01:01 | 4.18 | 230.3 | 0.96 | 90 | 0.96 | 0.84 | 16
cu1.cb1.r2 | 客户 1 | 12.01.a1 | 2012-01-02 | 00:01:01 | 4.51 | 229.32 | 1.03 | 21 | 1.03 | 0.85 | 15
cu1.cb1.r2 | 客户 1 | 12.01.a1 | 2012-01-02 | 01:01:01 | 4.18 | 230.3 | 0.96 | 23 | 0.96 | 0.84 | 16
cu1.cb1.s2 | 客户 2 | 10.01.a1 | 2012-01-02 | 00:01:01 | 7.34 | 228.14 | 1.67 | 179 | 1.67 | 0.88 | 24009
cu1.cb1.s2 | 客户 2 | 10.01.a1 | 2012-01-02 | 01:01:01 | 9.07 | 228.4 | 2.07 | 182 | 2.07 | 0.85 | 24010
cu1.cb1.s3 | 客户 2 | 10.01.a1 | 2012-01-02 | 00:01:01 | 7.34 | 228.14 | 1.67 | 121 | 1.67 | 0.88 | 24009
cu1.cb1.s3 | 客户 2 | 10.01.a1 | 2012-01-02 | 01:01:01 | 9.07 | 228.4 | 2.07 | 124 | 2.07 | 0.85 | 24010
cu1.cb1.r1 | 客户 3 | 01.01.a1 | 2012-01-02 | 00:01:01 | 7.32 | 229.01 | 1.68 | 223 | 1.68 | 0.89 | 48003
cu1.cb1.r1 | 客户 3 | 01.01.a1 | 2012-01-02 | 01:01:01 | 6.61 | 228.29 | 1.51 | 226 | 1.51 | 0.88 | 48004
cu1.cb1.r4 | 客户 3 | 01.01.a1 | 2012-01-02 | 00:01:01 | 7.32 | 229.01 | 1.68 | 215 | 1.68 | 0.89 | 48003
cu1.cb1.r4 | 客户 3 | 01.01.a1 | 2012-01-02 | 01:01:01 | 6.61 | 228.29 | 1.51 | 217 | 1.51 | 0.88 | 48004

如您所见,每个客户现在都有多个电路。因此,结果现在将是每个客户每个电路的每个最早 kwh 读数的总和,因此该表中的结果将是;

customer_name | kwh(sum)
--------------+-----------
customer 1    | 108      (the result of 87 + 21)  
customer 2    | 300      (the result of 179 + 121)  
customer 3    | 438      (the result of 223 + 215)   

每个客户将有超过 2 个电路,并且读数可能发生在不同的时间,因此需要“最早”读数。

有人对修改后的问题有什么建议吗?

CentOs/Redhat 上的 PostgreSQL 8.4。

4

2 回答 2

2
SELECT customer_name, sum(kwh) AS kwh_total
FROM  (
    SELECT DISTINCT ON (customer_name, circuit_uid)
           customer_name, circuit_uid, kwh
    FROM   readings
    WHERE  reading_date = '2012-01-02'::date
    ORDER  BY customer_name, circuit_uid, reading_time
    ) x
GROUP  BY 1

和以前一样,只挑最早的每(customer_name, circuit_uid)
然后求和customer_name

指数

像下面这样的多列索引将使这非常快:

CREATE INDEX readings_multi_idx
ON readings(reading_date, customer_name, circuit_uid, reading_time);
于 2012-11-17T19:06:33.587 回答
1

这是您原始问题的扩展:

select customer_name,
       sum(kwh)
from (
   select customer_name,
          kwh,
          reading_time,
          reading_date,
          row_number() over (partition by customer_name, circuit_uid order by reading_time) as rn
   from readings
   where reading_date = date '2012-01-02'
) t
where rn = 1
group by customer_name

请注意sum()外部查询中的新定义和内部查询中更改的partition by定义(与您之前的问题相比),它计算每个circuit_uid现在的第一个读数(而不是每个客户的第一个读数)。

于 2012-11-17T19:05:53.570 回答