当前位置: 首页 > 面试题库 >

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

龚凌
2023-03-14
问题内容

说我们有一张桌子:

CREATE TABLE p
(
   id serial NOT NULL, 
   val boolean NOT NULL, 
   PRIMARY KEY (id)
);

填充一些行:

insert into p (val)
values (true),(false),(false),(true),(true),(true),(false);



身份验证
1 1
2 0
3 0
4 1
5 1
6 1
7 0

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

身份验证
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小提琴


问题答案:

这就是我如何通过分析来做到这一点:

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

更新(一些解释):

分析功能充当后处理步骤。查询结果分为多个分组(partition by),并且在分组的上下文中应用了分析功能。

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

然后,我们查找与上一行(prev_val)val不匹配的val行。该COALESCE句柄处理不具有先前值的第一行的特殊情况。

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



 类似资料:
  • 问题内容: 我需要帮助或想法如何编写它,一个mysql语句。当特定列的值更改时,我需要选择一行。此后具有相同值的行不应选择。例如,我们有一个像这样的表,用以下值填充: 如果我想在status_1更改时选择行,则查询应选择ID为1和5的行,如果我正在使用status_2的ID为:1、3、5、7的行,并且如果我使用status_3的所有ID,则为ID 。希望有人可以在过去的所有时间里为我提供帮助。 提

  • 问题内容: 我需要将时间戳记值转换为查询中的纪元。请找到以下示例表和预期结果。 样表: 预期结果: 日志表的行数为n。请找到以下版本详细信息: 问题答案: 使用extract()函数: 显然,您的列不是timestamp列,而是a ,因此您首先需要将其转换为实际时间戳,然后才能使用 仅当该列中的所有值均具有正确的时间戳ISO格式时,此方法才起作用。 这告诉你,你应该 永远不要将日期,时间戳或时间值

  • 问题内容: 我有一张桌子,上面有我所有顾客购买的东西。我想选择上周(从周日开始的一周)中的所有条目。 我已经试过了: 但是我得到了上周的数据,包括本周的数据,我只想要上周的数据。 如何只获取上周的数据? 问题答案: 此条件将返回上周日至周六的记录: 有一个例子: 在对@ d456的回答中: 在间隔的两端不使用星期日的午夜吗? 没错,包括间隔两端的周日午夜。要在间隔结束时排除周日的午夜,必须使用运算

  • 问题内容: 我发现了具有正确答案的类似问题。但是它们对我来说有点复杂。我只想要一个简单的基本声明。 我有: …和: 如何合并它们? 问题答案: 有关OUTPUT子句的更多信息,请查看此文章。

  • 问题内容: 在hibernate状态下,我可以执行以下操作 现在,如果我想获取int和String怎么办? 现在列表的结构是什么? 问题答案: 这可以。您唯一需要了解的是它将返回如下列表:

  • 我正在使用Spring数据jpa来创建服务。使用我从多个表中提取记录。我在模型类中使用了映射。模型类与和进行映射。相符。 我只想从建筑中选择建筑名称。 谁能告诉我怎么办? 查询DSL 结果