Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
运行总数为;“火柴”;在SQL中使用窗口函数_Sql_Postgresql_Aggregate Functions_Window Functions - Fatal编程技术网

运行总数为;“火柴”;在SQL中使用窗口函数

运行总数为;“火柴”;在SQL中使用窗口函数,sql,postgresql,aggregate-functions,window-functions,Sql,Postgresql,Aggregate Functions,Window Functions,我想创建一个窗口函数,该函数将计算当前行中字段的值在有序分区中位于当前行之前的部分中出现的次数。为了使这更具体,假设我们有这样一张表: | id| fruit | date | +---+--------+------+ | 1 | apple | 1 | | 1 | cherry | 2 | | 1 | apple | 3 | | 1 | cherry | 4 | | 2 | orange | 1 | | 2 | grape | 2 | | 2 |

我想创建一个窗口函数,该函数将计算当前行中字段的值在有序分区中位于当前行之前的部分中出现的次数。为了使这更具体,假设我们有这样一张表:

| id| fruit  | date |
+---+--------+------+
| 1 | apple  |   1  |
| 1 | cherry |   2  |
| 1 | apple  |   3  |
| 1 | cherry |   4  |
| 2 | orange |   1  |
| 2 | grape  |   2  |
| 2 | grape  |   3  |
我们希望创建这样一个表(为了清楚起见,省略日期列):

请注意,对于
id=1
,沿着有序分区移动,第一个条目“apple”与任何内容都不匹配(因为隐含的集合为空),下一个水果“cherry”也不匹配。然后我们再来看“苹果”,这是一场比赛,以此类推。我想象SQL是这样的:

SELECT
id, fruit, 
<some kind of INTERSECT?> OVER (PARTITION BY id ORDER by date) AS prior
FROM fruit_table; 
选择
身份证,水果,
如上所述(按id划分,按日期排序)
从水果桌;

但是我找不到任何看起来合适的东西。FWIW,我正在使用PostgreSQL 8.4。

如果没有窗口函数,您可以通过自左连接和
计数()优雅地解决这个问题:

  • 这是可行的,因为我:
如果省略帧_end,则默认为当前行

  • 您可以有效地计算前几天有多少行具有相同的
    (id,水果)
    ,包括当前行。这就是
    -1
    的作用
是否保证“日期”是连续的?(顺便说一句,“date”是保留字。“previor”在某些SQL实现中也是保留字)
SELECT
id, fruit, 
<some kind of INTERSECT?> OVER (PARTITION BY id ORDER by date) AS prior
FROM fruit_table; 
SELECT t.id, t.fruit, t.day, count(t0.*) AS prior
FROM   tbl t
LEFT   JOIN tbl t0 ON (t0.id, t0.fruit) = (t.id, t.fruit) AND t0.day < t.day
GROUP  BY t.id, t.day, t.fruit
ORDER  BY t.id, t.day
SELECT id, fruit, day
      ,count(*) OVER (PARTITION BY id, fruit ORDER BY day) - 1 AS prior
FROM   tbl
ORDER  BY id, day