
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
我想确定何时更改了值.所以我的查询结果应该是:
ID VAL2 04 17 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) tmpgroup by val,last_prevorder 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请记住,这是一个后处理步骤.除非您对其进行子查询,否则您将无法对分析函数的值执行过滤等 *** 作.
总结以上是内存溢出为你收集整理的PostgreSQL – 列值已更改 – 选择查询优化全部内容,希望文章能够帮你解决PostgreSQL – 列值已更改 – 选择查询优化所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)