9

次のような行番号でビューを作成しようとしています:

create or replace view daily_transactions as
select 
    generate_series(1, count(t)) as id,        
    t.ic,
    t.bio_id,
    t.wp,    
    date_trunc('day', t.transaction_time)::date transaction_date, 
    min(t.transaction_time)::time time_in, 
    w.start_time wp_start,    
    w.start_time - min(t.transaction_time)::time in_diff,    
    max(t.transaction_time)::time time_out,     
    w.end_time wp_end,    
    max(t.transaction_time)::time - w.end_time out_diff,     
    count(t) total_transactions,
    calc_att_status(date_trunc('day', t.transaction_time)::date,
                    min(t.transaction_time)::time,
                    max(t.transaction_time)::time,
                    w.start_time, w.end_time ) status        
from transactions t
left join wp w  on (t.wp = w.wp_name)
group by ic, bio_id, t.wp, date_trunc('day', transaction_time),
         w.start_time, w.end_time;

行が重複してしまいました。SELECT DISTINCTどちらも機能しません。何か案は?

トランザクション テーブル:

create table transactions(
    id serial primary key,    
    ic text references users(ic),
    wp text references wp(wp_name),
    serial_no integer,    
    bio_id integer,
    node integer,
    finger integer,
    transaction_time timestamp,    
    transaction_type text,        
    transaction_status text        
 );

WP テーブル:

create table wp(
    id serial unique,   
    wp_name text primary key,
    start_time time,
    end_time time,
    description text,
    status text    
);

出力を表示:

出力を表示

4

1 に答える 1

23
CREATE OR REPLACE VIEW daily_transactions as
SELECT row_number() OVER () AS id
     , t.ic
     , t.bio_id
     , t.wp 
     , t.transaction_time::date AS transaction_date
     , min(t.transaction_time)::time AS time_in
     , w.start_time AS wp_start
     , w.start_time - min(t.transaction_time)::time AS in_diff
     , max(t.transaction_time)::time AS time_out
     , w.end_time AS wp_end
     , max(t.transaction_time)::time - w.end_time AS out_diff
     , count(*) AS total_transactions
     , calc_att_status(t.transaction_time::date, min(t.transaction_time)::time
                     , max(t.transaction_time)::time
                     , w.start_time, w.end_time) AS status
FROM   transactions t
LEFT   JOIN wp w ON t.wp = w.wp_name
GROUP  BY t.ic, t.bio_id, t.wp, t.transaction_time::date
        , w.start_time, w.end_time;

主なポイント

  • generate_series()は集計関数の後に適用されますが、複数の行が生成されるため、すべての出力行が乗算されます。ウィンドウ関数も集計関数の後に適用さ
    ますが、行ごとに 1 つの数値しか生成しません。そのためには PostgreSQL 8.4 以降が必要です。row_number()

  • date_trunc()では冗長ですdate_trunc('day', t.transaction_time)::date
    t.transaction_time::date同じことをより簡単に、より速く実現します。

  • count(*)の代わりに使用しcount(t)ます。ここでも同じ結果ですが、少し高速です。

その他いくつかの小さな変更。

于 2011-12-26T19:16:05.237 に答える