标签: window-functions

last_value() 窗口函数到底做了什么?

在测试我对SQL 的回答- 从每个组的第一行和最后一行获取数据时,我注意到一些奇怪的事情。在first_valuelast_value窗口功能,出现不同的表现。

正如预期的那样,从具有最小值的行中first_value(col1) over (order by col2)找到 的值。但似乎找到了当前行的值。 似乎与其操作的组或分区无关。col1col2last_value(col1) over (order by col2)last_value

对于下面的查询:

id  Session ID  bal
0   00000002    100
1   00000002    120
2   00000002    140
3   00000001    900
4   00000001    800
5   00000001    500
Run Code Online (Sandbox Code Playgroud)

表达方式:

last_value(bal) over (partition by [Session ID] order by id) as lv
Run Code Online (Sandbox Code Playgroud)

返回与以下内容不同的内容:

first_value(bal) over (partition by [Session ID] order by id DESC) as fv_desc
Run Code Online (Sandbox Code Playgroud)

结果如下(注意lv一组内的值变化):

lv …
Run Code Online (Sandbox Code Playgroud)

sql-server window-functions

6
推荐指数
1
解决办法
3772
查看次数

返回总行数和选定(聚合)数据

我有一个从表格中选择一些数据的功能。我想返回所选数据和该表中的总行数。

我怎样才能做到这一点,或者我怎样才能以最有效的方式获得相同的结果?

我尝试了几件事,最后得到了下面的代码,现在这是我想要的格式,但count(*) over () as total_count会一直返回 1,我需要它返回的是该records选择的总行数。

SELECT 
row_to_json(selected_records) as data
FROM
(   
    SELECT
    count(*) over () as total_count,
    array_to_json(array_agg(row_to_json(records))) as data
    FROM (
        SELECT
            sum(entrances) as entrances
        FROM report_la
        WHERE profile_id = 3777614
        GROUP BY landing_path_id
        limit 10 offset 0
    ) records
) as selected_records
Run Code Online (Sandbox Code Playgroud)

更新,下面的代码产生了我想要的结果,如果我可以total_countrecords选择中隐藏该列就好了

SELECT 
row_to_json(selected_records) as data
FROM
(   
    SELECT
    min(total_count) as total_count
    ,array_to_json(array_agg(row_to_json(records))) as data
    FROM (
        SELECT
            sum(entrances) as entrances
            ,count(*) over () as total_count …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate window-functions postgresql-9.3

6
推荐指数
1
解决办法
2万
查看次数

检查是否存在连续的日期间隔

我在 PostgreSQL 中有一个表,它描述了一些具有开始日期和结束日期的事件:

CREATE TABLE my_table
(
  event_id serial NOT NULL,
  start_date timestamp without time zone NOT NULL,
  end_date timestamp without time zone NOT NULL
)
Run Code Online (Sandbox Code Playgroud)

单个事件可能与前一个和下一个事件重叠。在下表中,4 个事件中的前 3 个形成连续的时间间隔:

1   '2015-04-02 22:09:03'   '2015-04-02 22:19:05'
2   '2015-04-02 22:17:38'   '2015-04-02 22:27:38'
3   '2015-04-02 22:25:21'   '2015-04-02 22:36:23'
4   '2015-04-02 22:45:23'   '2015-04-02 22:55:23'
Run Code Online (Sandbox Code Playgroud)

是否可以编写一个查询来检查两个给定日期之间是否存在连续的日期间隔?

我想要一些类似的东西:

select ...
from my_table
where start_date > '2015-04-02' and end_date < '2015-04-06'
Run Code Online (Sandbox Code Playgroud)

postgresql window-functions gaps-and-islands

6
推荐指数
1
解决办法
7138
查看次数

Calculate 40 day moving average w.r.t to a field

I have a table that stores the information about user calls in a call center. The table has a call_id, date when the call was made, actual date and time of the call, call type and a score associated with the call.

My requirement is to calculate a 40 day moving average of the score with respect to the call day. The 40 day should start from the previous day from the call date. If there are no call in …

postgresql window-functions postgresql-9.4

6
推荐指数
1
解决办法
3047
查看次数

用单个输入数字逐行减法

我想从前一行减法结果中动态减去,作为输入,我想给出一个数字。

我有桌子 a

CREATE TABLE a (id int, code text, qty numeric);
Run Code Online (Sandbox Code Playgroud)

还有里面的数据

INSERT INTO a (id,code,qty)
(1,'test',5),
(2,'test',3),
(3,'test',10);
Run Code Online (Sandbox Code Playgroud)

1.sample - 当输入是16- 期望的结果是:

id | qty
--------------
1  | 0
2  | 0
3  | 2
Run Code Online (Sandbox Code Playgroud)

计算将是这样的

case when 16 > 5 then 16-5 else 5-16 end /* result 11, but displayed 0 */
case when 11 > 3 then 11-3 else 3-11 end /* result 8, but displayed 0 */
case when 8 > 10 then …
Run Code Online (Sandbox Code Playgroud)

postgresql window-functions

6
推荐指数
1
解决办法
2809
查看次数

基于某个类别的前 n 个列的总和

我有以下输入,我需要计算每个类别前 x 周数的值的总和。

输入

如果 x 为 3,输出将如下所示:

在此处输入图片说明

请注意,最后一个值为 49,因为自 x=3 以来,它仅将上周的值添加到当前周。

我希望将 SQL 编写为存储过程,并且需要一些有关执行此操作的适当方法的帮助。

在@sp_BlitzErik 的帮助下,我尝试使用LAG,但无法完全到达我需要的地方。这是我的查询:

SELECT category
    ,year
    ,week
    ,value
    ,(
        LAG(value, 1, 0) OVER (
            ORDER BY category
                ,year
                ,week
            ) + LAG(value, 2, 0) OVER (
            ORDER BY category
                ,year
                ,week
            ) + value
        ) AS cumulative_value
FROM valuedata
Run Code Online (Sandbox Code Playgroud)

输出还不太正确:

在此处输入图片说明

sql-server aggregate t-sql window-functions

6
推荐指数
1
解决办法
4万
查看次数

PostgreSQL 的窗口函数 IGNORE NULLS 解决方法

通过以下查询,我可以使用 LAG() 函数重复列的最后一个非空值c

SELECT coalesce(open_time, extract(EPOCH from date_trunc('minute', datetime)) * 1000)               open_time,
   coalesce(o, LAG(c) over w)                                                                          o,
   coalesce(h, LAG(c) over w)                                                                          h,
   coalesce(l, LAG(c) over w)                                                                          l,
   coalesce(c, LAG(c) over w)                                                                          c,
   coalesce(v, 0)                                                                                      v,
   coalesce(close_time, extract(EPOCH from date_trunc('minute', datetime)) * 1000 + ((60000 * 1) - 1)) close_time
from temporary_timeframe 
window w as (order by datetime);
Run Code Online (Sandbox Code Playgroud)

得到以下结果:

在此处输入图片说明

但是我需要c在当前列值为空时重复列的值。我看到如果 PostgreSQL 支持IGNORE NULLS窗口函数的属性,这将得到解决。如何解决这个没有IGNORE NULLS

postgresql window-functions

6
推荐指数
1
解决办法
5120
查看次数

更智能的 ntile

使用ntile()窗口函数时,主要问题是它随意分组为大致相等的部分,而不管实际值如何。

例如使用以下查询:

select
    id,title,price,
    row_number() over(order by price) as row_number,
    rank() over(order by price) as rank,
    count(*) over(order by price) as count,
    dense_rank() over(order by price) as dense_rank,
    ntile(10) over(order by price) as decile
from paintings
order by price;
Run Code Online (Sandbox Code Playgroud)

我会得到 10 组大小大致相同的画作,很有可能以相同的价格结束在不同的箱子里。

例如:

select
    id,title,price,
    row_number() over(order by price) as row_number,
    rank() over(order by price) as rank,
    count(*) over(order by price) as count,
    dense_rank() over(order by price) as dense_rank,
    ntile(10) over(order by price) as decile
from paintings
order …
Run Code Online (Sandbox Code Playgroud)

postgresql sql-server window-functions rank

6
推荐指数
1
解决办法
537
查看次数

COUNT(1) OVER (PARTITION BY NULL) 的性能损失

在我的应用程序服务器中,我想使用LIMIT和对数据集进行分页OFFSET,并另外将数据集的总数返回给用户。

而不是对数据库进行两次远程调用:

select count(1) as total_count from foo;
select c1 from foo;
Run Code Online (Sandbox Code Playgroud)

我认为在单个数据库调用中完成此操作会更明智:

select c1, count(1) over (partition by null) from foo;
Run Code Online (Sandbox Code Playgroud)

但是,与不使用窗口函数相比,添加此窗口函数会导致执行时间长一个数量级。

我觉得这很令人惊讶,因为类似的时间select count(1) from foo只需要两倍的时间select c1 from foo。然而,将其转换为窗口函数会导致性能下降。

此外,使用以下使用子查询的替代方案非常快:

select c1, (select count(1) from foo) as total_count from foo;
Run Code Online (Sandbox Code Playgroud)

我本来期望 postgresql 能够优化partition by null

我在 Oracle 中尝试过这一点,发现了类似的性能损失。

如何解释为什么这里会出现性能损失?对于核心 postgresql 开发人员来说,进行更改以优化这一点是否相对容易,甚至值得,例如通过将 PARTITION BY NULL 的窗口函数转换为子查询?


设置:

drop table foo;
create table foo (c1 int);

insert into foo
select i from …
Run Code Online (Sandbox Code Playgroud)

postgresql count window-functions postgresql-performance postgresql-13

6
推荐指数
1
解决办法
4772
查看次数

使用 Postgres 继承缺失值的长序列

我有一张这样的表:

create table foo (foo_label text, foo_price int, foo_date date);

insert into foo (
          values
          ('aaa', 100,  '2017-01-01'),
          ('aaa', NULL, '2017-02-01'),
          ('aaa', NULL, '2017-03-01'),
          ('aaa', NULL, '2017-04-01'),
          ('aaa', 140,  '2017-05-01'),
          ('aaa', NULL, '2017-06-01'),
          ('aaa', 180,  '2017-07-01')
        );
Run Code Online (Sandbox Code Playgroud)

如您所见,foo_price列上的一些值丢失了。

我需要的是缺失值以这种方式用“前一个”可用值填充:

 foo_label | fixed_foo_price | foo_date
-----------+-----------------+------------
 aaa       | 100             | 2017-01-01
 aaa       | 100             | 2017-02-01
 aaa       | 100             | 2017-03-01
 aaa       | 100             | 2017-04-01
 aaa       | 140             | 2017-05-01
 aaa       | 140             | 2017-06-01
 aaa       | 180 …
Run Code Online (Sandbox Code Playgroud)

postgresql null count window-functions gaps-and-islands

5
推荐指数
1
解决办法
2225
查看次数