Ant*_*al' 1 postgresql window-functions
假设我们有以下查询。
\nselect\n name,\n pos,\n rank() over (partition by constructor) r,\n format('%s / %s',\n row_number() over (partition by constructor),\n count(*) over (partition by constructor)\n ) "pos/global"\nfrom (values\n ('d1-c1', 1, 'c1'),\n ('d3-c1', 3, 'c1'),\n ('d3-c2', 3, 'c2'),\n ('d2-c1', 2, 'c1'),\n ('d2-c2', 2, 'c2')\n ) t(name, pos, constructor);\n
Run Code Online (Sandbox Code Playgroud)\n输出如下:
\n name \xe2\x94\x82 pos \xe2\x94\x82 r \xe2\x94\x82 pos/global\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n d1-c1 \xe2\x94\x82 1 \xe2\x94\x82 1 \xe2\x94\x82 1 / 3\n d3-c1 \xe2\x94\x82 3 \xe2\x94\x82 1 \xe2\x94\x82 2 / 3\n d2-c1 \xe2\x94\x82 2 \xe2\x94\x82 1 \xe2\x94\x82 3 / 3\n d3-c2 \xe2\x94\x82 3 \xe2\x94\x82 1 \xe2\x94\x82 1 / 2\n d2-c2 \xe2\x94\x82 2 \xe2\x94\x82 1 \xe2\x94\x82 2 / 2\n(5 rows)\n
Run Code Online (Sandbox Code Playgroud)\n(此处可选问题:为什么每帧中的所有行都排名为1
?)
但是当我更改框架规范中的顺序时,
\nselect\n name,\n pos,\n rank() over (partition by constructor order by pos asc) r,\n format('%s / %s',\n row_number() over (partition by constructor),\n count(*) over (partition by constructor)\n ) "pos/global"\nfrom (values\n ('d1-c1', 1, 'c1'),\n ('d3-c1', 3, 'c1'),\n ('d3-c2', 3, 'c2'),\n ('d2-c1', 2, 'c1'),\n ('d2-c2', 2, 'c2')\n ) t(name, pos, constructor);\n
Run Code Online (Sandbox Code Playgroud)\n,我明白了:
\n name \xe2\x94\x82 pos \xe2\x94\x82 r \xe2\x94\x82 pos/global\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n d1-c1 \xe2\x94\x82 1 \xe2\x94\x82 1 \xe2\x94\x82 1 / 3\n d2-c1 \xe2\x94\x82 2 \xe2\x94\x82 2 \xe2\x94\x82 2 / 3\n d3-c1 \xe2\x94\x82 3 \xe2\x94\x82 3 \xe2\x94\x82 3 / 3\n d2-c2 \xe2\x94\x82 2 \xe2\x94\x82 1 \xe2\x94\x82 1 / 2\n d3-c2 \xe2\x94\x82 3 \xe2\x94\x82 2 \xe2\x94\x82 2 / 2\n(5 rows)\n
Run Code Online (Sandbox Code Playgroud)\n...这就是我想要的,但我不明白为什么框架的顺序会影响所有其他行的顺序。我的直觉表明输出应该是这样的(只有r
列中的值发生变化):
name \xe2\x94\x82 pos \xe2\x94\x82 r \xe2\x94\x82 pos/global\n\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\xaa\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\xe2\x95\x90\n d1-c1 \xe2\x94\x82 1 \xe2\x94\x82 1 \xe2\x94\x82 1 / 3\n d3-c1 \xe2\x94\x82 3 \xe2\x94\x82 3 \xe2\x94\x82 2 / 3\n d2-c1 \xe2\x94\x82 2 \xe2\x94\x82 2 \xe2\x94\x82 3 / 3\n d3-c2 \xe2\x94\x82 3 \xe2\x94\x82 3 \xe2\x94\x82 1 / 2\n d2-c2 \xe2\x94\x82 2 \xe2\x94\x82 2 \xe2\x94\x82 2 / 2\n(5 rows)\n
Run Code Online (Sandbox Code Playgroud)\n
该rank()
函数按指定的顺序对行进行排名,您没有指定任何顺序,也没有固有的顺序,因此行是“相等的”并且全部都 get 1
。在第二个查询中,您提供了一个顺序,它开始按预期工作。
对于主要问题 - 如果您没有为查询结果指定任何排序依据(您在任何一个查询中都没有指定排序依据),那么结果行的顺序是未定义的,数据库可以按照它喜欢的任何顺序返回它们(同一查询的两次执行之间可能有所不同)。通常优化器会尝试做尽可能少的工作来满足查询。
values
因为不需要更改任何内容rank()
,并且由于该查询中不需要其他顺序,因此优化器决定values
直接对行进行排序并将其用于输出(因为它仍然满足“未定义”最终)排序) - 不知道“优化器决定”是某种实际的优化还是只是代码中其他交互的副作用,实际上并不重要:) 归档时间: |
|
查看次数: |
444 次 |
最近记录: |