加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

PostgreSQL – 列值已更改 – 选择查询优化

发布时间:2020-12-13 16:31:22 所属栏目:百科 来源:网络整理
导读:假设我们有一张桌子: CREATE TABLE p( id serial NOT NULL,val boolean NOT NULL,PRIMARY KEY (id)); 填充了一些行: insert into p (val)values (true),(false),(true),(false); ID VAL1 12 03 04 15 16 17 0 我想确定何时更改了值.所以我的查询结果应该是
假设我们有一张桌子:
CREATE TABLE p
(
   id serial NOT NULL,val boolean NOT NULL,PRIMARY KEY (id)
);

填充了一些行:

insert into p (val)
values (true),(false),(true),(false);
ID  VAL
1   1
2   0
3   0
4   1
5   1
6   1
7   0

我想确定何时更改了值.所以我的查询结果应该是:

ID  VAL
2   0
4   1
7   0

我有一个连接和子查询的解决方案:

select min(id) id,val from
(
  select p1.id,p1.val,max(p2.id) last_prev
  from p p1
  join p p2
    on p2.id < p1.id and p2.val != p1.val
  group by p1.id,p1.val
) tmp
group by val,last_prev
order by id;

但它的效率非常低,对于有很多行的表来说效果会非常慢.
我相信使用PostgreSQL窗口函数可以提供更有效的解决方案吗?

SQL Fiddle

这就是我用分析方法做的事情:
SELECT id,val
  FROM ( SELECT id,val,LAG(val) OVER (ORDER BY id) AS prev_val
       FROM p ) x
  WHERE val <> COALESCE(prev_val,val)
  ORDER BY id

更新(一些解释):

分析函数用作后处理步骤.查询结果分为分组(分区依据),分析函数应用于分组的上下文中.

在这种情况下,查询是从p的选择.正在应用的分析函数是LAG.由于没有partition by子句,因此只有一个分组:整个结果集.此分组按ID排序. LAG使用指定的顺序返回分组中上一行的值.结果是每行都有一个附加列(别名prev_val),它是前一行的val.那是子查询.

然后我们查找val与前一行的val(prev_val)不匹配的行. COALESCE处理第一行的特殊情况,它没有以前的值.

分析函数起初可能看起来有点奇怪,但是对分析函数的搜索会发现很多例子都在讨论它们的工作原理.例如:http://www.cs.utexas.edu/~cannata/dbms/Analytic%20Functions%20in%20Oracle%208i%20and%209i.htm请记住,这是一个后处理步骤.除非您对其进行子查询,否则您将无法对分析函数的值执行过滤等操作.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读