标签: window-functions

如何让 row_number 具有dense_rank 的行为

我有一个存储过程将用于分页数据。该过程的要求之一是有一个参数将用于对两列数据进行排序,在应用row_number().

一些示例数据:

CREATE TABLE grp 
(
  [grp_id] uniqueidentifier primary key, 
  [grp_nm] varchar(5) not null, 
  [grp_owner] varchar(200) not null
);

INSERT INTO grp ([grp_id], [grp_nm], [grp_owner])
VALUES
    ('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 'test1', 'me'),
    ('1F52A713-EFAC-E211-9C26-78E7D18E1E84', 'test2', 'me'),
    ('D123B48A-63AB-E211-9C26-78E7D18E1E84', 'test3', 'me'),
    ('48361F86-2BC2-E211-9C26-78E7D18E1E84', 'test4', 'me'),
    ('27429A57-93C1-E211-9C26-78E7D18E1E84', 'test5', 'me'),
    ('D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84', 'test6', 'me'),
    ('9A07EA21-1AAD-E211-9C26-78E7D18E1E84', 'test7', 'me');


CREATE TABLE mbr
(
  [grp_id] uniqueidentifier, 
  [mbr_id] int not null primary key, 
  [acct_id] varchar(7) not null, 
  [cst] varchar(4) null
);

INSERT INTO mbr ([grp_id], [mbr_id], [acct_id], [cst])
VALUES
    ('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 10, '1', …
Run Code Online (Sandbox Code Playgroud)

sql-server window-functions

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

根据当前行和下一行之间的时间差进行过滤

我有一个具有以下结构的数据库表:

id     | created
-------+---------------
1      | 2018-07-23 00:01:00
2      | 2018-07-23 00:02:00
...
Run Code Online (Sandbox Code Playgroud)

现在我想返回与下一行的时间差大于 10 秒的所有行。

我尝试过使用 Postgres 窗口函数,但无法让它工作,例如

SELECT
  created, 
  created - lag(created, 1) OVER (ORDER BY created) delta
FROM tablename
where created - lag(created, 1)  OVER (ORDER BY created) > interval '10 seconds'
ORDER BY created;
Run Code Online (Sandbox Code Playgroud)

我得到的错误是我不允许在WHERE子句中使用窗口函数。如何做到这一点?

postgresql window-functions

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

选择第一行(分组)+添加聚合函数

首先看看StackOverflow上的这个问题

我希望完成相同的任务,但我还需要ST_Union向我的查询添加聚合函数(PostGIS )。

如何将答案DISTINCT与聚合结合使用...

我试过了:

SELECT DISTINCT ON (name, zonedistrict_id)
       ST_Union(geom) as geom, gid, name, zonedistrict_id, zonestyle_id, longname 
FROM zones
ORDER BY name, zonedistrict_id, zonestyle_id;
Run Code Online (Sandbox Code Playgroud)

哪个尖叫:

column "zones.gid" must appear in the GROUP BY clause or be used in an aggregate function

这很奇怪,因为如果我删除ST_Union(geom) as geom,,则查询有效。但它没有联合几何。

postgresql aggregate window-functions postgis

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

选择第 n 个百分位的行

我有两张桌子,table1table2。让这两个表包含日期、ID 和延迟列。

我有一个简单的查询,它对两个表执行连接并返回一组行:

Select table1.date,(table2.latency - table1.latency) as ans from table1, table2
where table1.id = table2.id order by ans;
Run Code Online (Sandbox Code Playgroud)

我需要从返回的行集中找到第 n 个百分位行,假设我需要从数据中找到 90%、99% 和 99.9% 的百分位行。

我需要以这样的形式显示数据:

    date       |   percentile  | ans
    01-12-1995 |    90         | 0.001563
    02-12-1999 |    99         | 0.0015
    05-12-2000 |    99.9       | 0.012
Run Code Online (Sandbox Code Playgroud)

这是我第一次接触 PostgreSQL。我很困惑我应该如何进行。

我正在看PERCENT_RANK()功能。请指导我正确的方向。

postgresql window-functions

3
推荐指数
1
解决办法
3438
查看次数

为行组添加总量列

我有一个 Items 表和一个 Inventory 表。一个项目可以属于多个库存记录。我正在尝试返回所有库存记录的列表,但在新列中包含它们的数量。例如:

项目

ItemID     ItemDescription
103        Headphones
115        Speakers
230        Wireless Adapter
275        20' Network Cable
Run Code Online (Sandbox Code Playgroud)

存货

InventoryID        ItemID        WarrantyDate       Status
1                  103           12/22/2010         Available
2                  103           05/15/2012         Available
3                  103           02/24/2015
4                  275           01/01/2010
5                  275           01/01/2011
Run Code Online (Sandbox Code Playgroud)

如果我尝试COUNT使用 ItemID 和GROUP BYItemID,如下所示:

SELECT ItemID, COUNT(ItemID) AS Quantity
FROM Inventory
GROUP BY ItemID
Run Code Online (Sandbox Code Playgroud)

我得到:

ItemID  Quantity
103     3
275     2        
Run Code Online (Sandbox Code Playgroud)

但我真正想要的是:

InventoryID        ItemID        WarrantyDate       Status       Quantity
1                  103           12/22/2010         Available    3
2                  103           05/15/2012 …
Run Code Online (Sandbox Code Playgroud)

sql-server aggregate sql-server-2012 window-functions

3
推荐指数
1
解决办法
843
查看次数

PostgreSQL ntile() 分区

我有一个带有人口值的点网格。每个点都有一个 id 和人口值。我也有一个 state_id,它说明了要点是什么状态。

现在我想计算每个州的百分位数 ntile(100)。

   SELECT  id, population, state_id, 
   ntile(100) OVER(ORDER BY car20) as percentile
   FROM avi_threshold01 
Run Code Online (Sandbox Code Playgroud)

当我使用它时,我认为它会计算所有点和状态的 ntile。

postgresql aggregate window-functions group-by

3
推荐指数
1
解决办法
7461
查看次数

在 PostgreSQL 中为滚动总和设置非负下限

这是一个非常有趣的问题(针对 SQL Server 提出的问题),我想尝试一下,看看它是如何在 PostgreSQL 中完成的。让我们看看其他人是否可以做得更好。拿着这个数据,

CREATE TABLE foo
AS
  SELECT pkid::int, numvalue::int, groupid::int
  FROM ( VALUES
    ( 1,  -1   , 1 ),
    ( 2,  -2   , 1 ),
    ( 3,  5    , 1 ),
    ( 4,  -7   , 1 ),
    ( 5,  1    , 2 )
  ) AS t(pkid, numvalue, groupid);
Run Code Online (Sandbox Code Playgroud)

我们正在尝试生成这个:

PKID   RollingSum    GroupID
----------------------------- ## Explanation: 
1      0             1        ## 0 - 1 < 0  => 0
2      0             1        ## 0 - 2 < 0 …
Run Code Online (Sandbox Code Playgroud)

postgresql aggregate window-functions running-totals

3
推荐指数
1
解决办法
4522
查看次数

显示一个字段中具有非唯一值的行

我熟悉如何聚合行,如这个答案所示:

我还熟悉如何使用 HAVING 子句过滤聚合结果。

我似乎无法理解(因此它会粘住)是如何根据值或比较其他行来过滤行,而不聚合它们。

我知道答案涉及一些有关窗口函数或窗口子句的内容,事实上我以前已经成功完成过。但我似乎并没有记住它是如何运作的;我觉得我错过了一些基本的东西。

举个例子,信息如下:

 fruit_name | some_field 
------------+------------
 apple      |       3.25
 apple      |        6.8
 apple      |        0.7
 orange     |        2.6
 banana     |        3.5
 banana     |       2.49
 cherry     |          1
 grapefruit |        2.6
 grapefruit |        2.7
Run Code Online (Sandbox Code Playgroud)

我想要获取行数(按水果名称)大于 1 的所有行,因此它应该如下所示:

 fruit_name | some_field 
------------+------------
 apple      |       3.25
 apple      |        6.8
 apple      |        0.7
 banana     |        3.5
 banana     |       2.49
 grapefruit |        2.6
 grapefruit |        2.7
Run Code Online (Sandbox Code Playgroud)

执行此操作的正确惯用方法是什么?

(如果可能的话,我想要一个 SQL 标准答案,如果有一种更简单的 Postgres 特定方法来做到这一点,我也想知道。)

postgresql select window-functions

3
推荐指数
1
解决办法
1855
查看次数

Count Over 根据 Order By 返回 Row_Number

基于我发现的一些有趣语法的快速问题。我有一个包含这些列的表:

ID INT,
DimBuyDetails_Id INT, 
WeekOfBuy INT,
Spots INT,
Retired BIT
Run Code Online (Sandbox Code Playgroud)

如果我运行此查询,我将得到ROW_NUMBER()而不是COUNT()

SELECT *
    , COUNT(ID) OVER (
        PARTITION BY DimBuyDetails_Id, WeekOfBuy
        ORDER BY ID --<
) AS ct
FROM Core.FactBuysPerWeek
Run Code Online (Sandbox Code Playgroud)

但是,如果我更改该ORDER BY条款,我会得到COUNT()

SELECT *
    , COUNT(ID) OVER (
        PARTITION BY DimBuyDetails_Id, WeekOfBuy
        ORDER BY DimBuyDetails_Id, WeekOfBuy --<Changed Order by here
) AS ct
FROM Core.FactBuysPerWeek
Run Code Online (Sandbox Code Playgroud)

有谁知道是什么原因造成的?

sql-server window-functions sql-server-2014

3
推荐指数
1
解决办法
3332
查看次数

使用 group by 和 window 函数减少表扫描

有一个我正在尝试改进的代码,如下所示(简单示例):

SELECT    DISTINCT a.col_a
         ,COALESCE(b1.col_c, b2.col_c, b3.col_c)
FROM      tab_a a
LEFT JOIN tab_b b1
          ON a.col_a = b1.col_a
             AND b1.col_b = 'blabla1'
LEFT JOIN tab_b b2
          ON a.col_a = b2.col_a
             AND b2.col_b = 'blabla2'
LEFT JOIN tab_b b3
          ON a.col_a = b3.col_a
             AND b3.col_b = 'blabla3';
Run Code Online (Sandbox Code Playgroud)

您可以使用以下脚本重新创建这些表

CREATE TABLE tab_a(col_a int)
CREATE TABLE tab_b(col_a INT, col_b VARCHAR(10), col_c INT)

INSERT INTO dbo.tab_a ( col_a ) VALUES ( 1 ), ( 2 ), ( 3 );

INSERT INTO dbo.tab_b ( col_a …
Run Code Online (Sandbox Code Playgroud)

sql-server window-functions sql-server-2016

3
推荐指数
1
解决办法
280
查看次数