【问题标题】:Generate id row for a view with grouping为具有分组的视图生成 id 行
【发布时间】:2012-01-28 02:24:39
【问题描述】:

我正在尝试使用如下所示的行号创建一个视图:

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    
);

查看输出:

【问题讨论】:

  • 您能否提供事务和 wp 表的架构和一些示例数据?
  • @TetonSig 我已经添加了表定义和示例数据。感谢您查看我的问题 :)
  • 谢谢,很有帮助。您能否为 wp 中的特定 wp_name 和交易中的匹配 wp 提供每个表中的一些示例记录。

标签: sql postgresql view window-functions sql-view


【解决方案1】:
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() 聚合函数之后应用,但会产生多行,从而将所有输出行相乘。
    window function row_number() 也应用在 聚合函数之后,但仅每行生成一个数字。为此,您需要 PostgreSQL 8.4 或更高版本。

  • date_trunc()date_trunc('day', t.transaction_time)::date 中是多余的。
    t.transaction_time::date 实现了相同的功能,更简单且更快。

  • 使用count(*) 而不是count(t)。这里的结果相同,但要快一些。

其他一些小改动。

【讨论】:

  • @ErwinBrandstetter:恭喜获得 10k ;)
  • @ErwinBrandstetter,谢谢它完美运行!解释也很好。
  • 您好...假设您想要在服务器中进行分页的 id... 会成功吗?还是我们需要物化视图?
  • @yucer:如果你想要快速,你需要索引支持,这需要物化 ID。因此,向 tabler 添加一列(如果可能!),或使用物化视图。见:stackoverflow.com/a/34291099/939860
  • @ErwinBrandstetter 我不希望它快速但准确。如果根据相同的对象(在这种情况下为事务和 wp)从类似的视图中查询,我的意思是相同的值。我以 row_number() OVER (PARTITION BY true) 结束,如下所示:dba.stackexchange.com/questions/56897/…
猜你喜欢
  • 1970-01-01
  • 2012-11-17
  • 1970-01-01
  • 2013-03-06
  • 2020-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多