标签: window-functions

MySql使用over子句的正确语法

使over子句在mysql中工作的正确语法是什么?

我希望看到每个用户发送的总短信数,而不用group by子句对其进行分组.

SELECT 
    username, 
    count(sentSmsId) OVER (userId) 
FROM 
    sentSmsTable,
    userTable
WHERE
    userId = sentUserId;
Run Code Online (Sandbox Code Playgroud)

mysql sql window-functions

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

Postgres窗口函数和异常分组

我正在尝试将一个查询放在一起,该查询将在一段时间内检索用户的统计信息(利润/损失)作为累积结果.

这是我到目前为止的查询:

SELECT p.name, e.date, 
    sum(sp.payout) OVER (ORDER BY e.date)
    - sum(s.buyin) OVER (ORDER BY e.date) AS "Profit/Loss" 
FROM result r 
    JOIN game g ON r.game_id = g.game_id 
    JOIN event e ON g.event_id = e.event_id 
    JOIN structure s ON g.structure_id = s.structure_id 
    JOIN structure_payout sp ON g.structure_id = sp.structure_id
                            AND r.position = sp.position 
    JOIN player p ON r.player_id = p.player_id 
WHERE p.player_id = 17 
GROUP BY p.name, e.date, e.event_id, sp.payout, s.buyin
ORDER BY p.name, e.date ASC
Run Code Online (Sandbox Code Playgroud)

查询将运行.但是,结果略有不正确.原因是一个人event可以有多个游戏(有不同的sp.payouts …

sql postgresql aggregate-functions window-functions

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

为派生表计算SQL Server ROW_NUMBER()OVER()

在一些其他数据库(例如DB2或Oracle ROWNUM)中,我可以省略ORDER BY排名函数子句中的OVER()子句.例如:

ROW_NUMBER() OVER()
Run Code Online (Sandbox Code Playgroud)

当与有序派生表一起使用时,这尤其有用,例如:

SELECT t.*, ROW_NUMBER() OVER()
FROM (
    SELECT ...
    ORDER BY
) t
Run Code Online (Sandbox Code Playgroud)

如何在SQL Server中进行模拟?我发现人们使用这个 技巧,但这是错误的,因为它对于派生表中的顺序会表现得非确定:

-- This order here ---------------------vvvvvvvv
SELECT t.*, ROW_NUMBER() OVER(ORDER BY (SELECT 1))
FROM (
    SELECT TOP 100 PERCENT ...
    -- vvvvv ----redefines this order here
    ORDER BY
) t
Run Code Online (Sandbox Code Playgroud)

一个具体的例子(可以在SQLFiddle看到):

SELECT v, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) RN
FROM (
  SELECT TOP 100 PERCENT 1 UNION ALL …
Run Code Online (Sandbox Code Playgroud)

sql t-sql sql-server window-functions ranking-functions

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

带有where子句的SQL窗口函数?

我正在尝试为用户关联两种类型的事件.我希望在"A"事件之前看到所有事件"B"以及该用户的最新事件"A".如何实现这一目标?特别是,我正试图在Postgres中做到这一点.

我希望在窗口函数中可以使用"where"子句,在这种情况下,我基本上可以使用"where event ='A'"来执行LAG(),但这似乎不可能.

有什么建议?

数据示例:

|user |time|event|
|-----|----|-----|
|Alice|1   |A    |
|Bob  |2   |A    |
|Alice|3   |A    |
|Alice|4   |B    |
|Bob  |5   |B    |
|Alice|6   |B    |
Run Code Online (Sandbox Code Playgroud)

期望的结果:

|user |event_b_time|last_event_a_time|
|-----|------------|-----------------|
|Alice|4           |3                |
|Bob  |5           |2                |
|Alice|6           |3                |
Run Code Online (Sandbox Code Playgroud)

sql postgresql window-functions

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

TSQL OVER子句:COUNT(*)OVER(ORDER BY a)

这是我的代码:

USE [tempdb];
GO

IF OBJECT_ID(N'dbo.t') IS NOT NULL
BEGIN
    DROP TABLE dbo.t
END
GO

CREATE TABLE dbo.t
(
    a NVARCHAR(8),
    b NVARCHAR(8)
);
GO

INSERT t VALUES ('a', 'b');
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('a', 'b');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('c', 'd');
INSERT t VALUES ('e', NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL);
INSERT t VALUES (NULL, NULL); …
Run Code Online (Sandbox Code Playgroud)

sql t-sql sql-server window-functions sql-server-2012

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

为postgres表中的每个组选择随机行

我有一张大致的表格:

id | category | link | caption | image
Run Code Online (Sandbox Code Playgroud)

我的目标是从表中的每个不同类别中获取表中所有类别的随机行.计划是将每一行分配给其各自类别的变量.

现在我正在使用类似的多个SELECT语句:

SELECT link, caption, image FROM table WHERE category='whatever' ORDER BY RANDOM() LIMIT 1

但这看起来不那么优雅,并且创建了更多的数据库,这是昂贵的.

我很确定在Postgres中使用窗口函数有一种方法可以做到这一点,但我对它们没有经验,我不完全确定如何使用它来获得我想要的东西.

谢谢你的帮助!

sql postgresql window-functions

11
推荐指数
1
解决办法
4783
查看次数

在稀疏表中选择一行第一个非空值

使用下表,

A | B    | C    | ts
--+------+------+------------------
1 | null | null | 2016-06-15 10:00
4 | null | null | 2016-06-15 11:00 
4 |    9 | null | 2016-06-15 12:00
5 |    1 |    7 | 2016-06-15 13:00
Run Code Online (Sandbox Code Playgroud)

如何在N行的运行窗口中选择每列的第一个非空值?例如,查询上表将导致:

A | B | C
--+---+---
1 | 9 | 7
Run Code Online (Sandbox Code Playgroud)

sql postgresql null window-functions

11
推荐指数
2
解决办法
9092
查看次数

Oracle中分页查询的速度

这对我来说是一个永无止境的话题,我想知道我是否会忽视某些事情.基本上我在应用程序中使用两种类型的SQL语句:

  1. 具有"后备"限制的常规查询
  2. 排序和分页查询

现在,我们正在谈论针对具有数百万条记录的表的一些查询,加入另外5个具有数百万条记录的表.显然,我们几乎不想获取所有这些,这就是为什么我们有上述两种方法来限制用户查询.

案例1非常简单.我们只添加一个额外的ROWNUM过滤器:

WHERE ...
  AND ROWNUM < ?
Run Code Online (Sandbox Code Playgroud)

这是非常快的,因为Oracle的CBO将考虑其执行计划考虑此过滤器,并可能应用一个FIRST_ROWS操作(类似于/*+FIRST_ROWS*/提示强制执行的操作).

然而,案例2对Oracle来说有点棘手,因为LIMIT ... OFFSET其他RDBMS中没有任何条款.因此,我们将"业务"查询嵌套在技术包装器中:

SELECT outer.* FROM (
  SELECT * FROM (
    SELECT inner.*, ROWNUM as RNUM, MAX(ROWNUM) OVER(PARTITION BY 1) as TOTAL_ROWS
    FROM (
      [... USER SORTED business query ...]
    ) inner
  ) 
  WHERE ROWNUM < ?
) outer
WHERE outer.RNUM > ?
Run Code Online (Sandbox Code Playgroud)

请注意,TOTAL_ROWS即使不获取所有数据,也会计算该字段以了解我们将拥有多少页.现在这个分页查询通常非常令人满意.但是时不时(正如我所说,在查询5M +记录时,可能包括非索引搜索),这运行2-3分钟.

编辑:请注意,潜在的瓶颈并不容易规避,因为在分页之前必须应用排序!

我想知道,这是最先进的模拟LIMIT ... OFFSET,包括TOTAL_ROWS在Oracle中,还是有更好的解决方案,设计会更快,例如使用ROW_NUMBER() …

sql performance oracle11g rownum window-functions

10
推荐指数
1
解决办法
4807
查看次数

GROUP BY由间隙分隔的连续日期

假设您(在Postgres 9.1中)有这样一个表:

date | value 
Run Code Online (Sandbox Code Playgroud)

它有一些空白(我的意思是:并非每个可能的日期在最小(日期)和最大(日期)之间有它的行).

我的问题是如何聚合这些数据,以便分别处理每个一致的组(没有间隙),如下所示:

min_date | max_date | [some aggregate of "value" column] 
Run Code Online (Sandbox Code Playgroud)

有什么想法怎么做?我相信这是可能的窗口功能,但是过了一段时间,试图lag()lead()我有点卡住了.

例如,如果数据是这样的:

 date          | value  
---------------+-------  
 2011-10-31    | 2  
 2011-11-01    | 8  
 2011-11-02    | 10  
 2012-09-13    | 1  
 2012-09-14    | 4  
 2012-09-15    | 5  
 2012-09-16    | 20  
 2012-10-30    | 10  
Run Code Online (Sandbox Code Playgroud)

输出(sum作为聚合)将是:

   min     |    max     |  sum  
-----------+------------+-------  
2011-10-31 | 2011-11-02 |  20  
2012-09-13 | 2012-09-16 |  30  
2012-10-30 | 2012-10-30 |  10  
Run Code Online (Sandbox Code Playgroud)

sql postgresql aggregate window-functions

10
推荐指数
1
解决办法
3713
查看次数

Spark和SparkSQL:如何模仿窗口功能?

描述

给定一个数据帧 df

id |       date
---------------
 1 | 2015-09-01
 2 | 2015-09-01
 1 | 2015-09-03
 1 | 2015-09-04
 2 | 2015-09-04
Run Code Online (Sandbox Code Playgroud)

我想创建一个运行计数器或索引,

  • 按相同的ID分组
  • 按该组中的日期排序,

从而

id |       date |  counter
--------------------------
 1 | 2015-09-01 |        1
 1 | 2015-09-03 |        2
 1 | 2015-09-04 |        3
 2 | 2015-09-01 |        1
 2 | 2015-09-04 |        2
Run Code Online (Sandbox Code Playgroud)

这是我可以通过窗口功能实现的,例如

val w = Window.partitionBy("id").orderBy("date")
val resultDF = df.select( df("id"), rowNumber().over(w) )
Run Code Online (Sandbox Code Playgroud)

不幸的是,Spark 1.4.1不支持常规数据帧的窗口函数:

org.apache.spark.sql.AnalysisException: Could not resolve window function 'row_number'. Note that, …
Run Code Online (Sandbox Code Playgroud)

scala window-functions apache-spark apache-spark-sql

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