带有 ASC 的 LAST_VALUE() 和带有 DESC 的 FIRST_VALUE 返回不同的结果

Posted

技术标签:

【中文标题】带有 ASC 的 LAST_VALUE() 和带有 DESC 的 FIRST_VALUE 返回不同的结果【英文标题】:LAST_VALUE() with ASC and FIRST_VALUE with DESC return different results 【发布时间】:2016-01-21 08:50:35 【问题描述】:

我在 Google BigQuery 中使用 LAST_VALUE() 窗口函数时遇到问题。

据我了解,以下两列应该返回相同的结果,但实际上它们返回的结果不同,似乎带有FIRST_VALUE() 的那一列是正确的。

SELECT
  FIRST_VALUE(status) OVER (PARTITION BY userId ORDER BY timestamp DESC), 
  LAST_VALUE(status) OVER (PARTITION BY userId ORDER BY timestamp ASC)
FROM
  [table]

我有错吗?

【问题讨论】:

无空值或重复值。更糟糕的是,使用 LAST_VALUE 的方法会为同一个 userId 返回不同的结果。 这是一个功能,而不是错误..检查下面的答案 您的费率很低。对 SO 很重要,您必须使用已发布答案左侧、投票下方的勾号来标记已接受的答案。这将提高您的费率。通过访问此链接了解其工作原理:meta.***.com/questions/5234/… SQL: Last_Value() returns wrong result (but First_Value() works fine)的可能重复 【参考方案1】:

当 OVER() 函数具有 (ORDER BY) 时,它们的工作方式有一个微妙之处:它们以增量方式工作。

查看此查询:

SELECT x, y, 
       FIRST_VALUE(x) OVER(ORDER BY y) first, 
       LAST_VALUE(x) OVER(ORDER BY y DESC) last,
       SUM(x) OVER() plain_sum_over, 
       SUM(x) OVER(ORDER BY y) sum_over_order
FROM (SELECT 1 x, 1 y),(SELECT 2 x, 2 y),(SELECT 3 x, 3 y),(SELECT 4 x, 4 y)

plain_sum_oversum_over_order 揭示了秘密:通过 ORDER BY,您可以获得递增的结果 - 这就是您在结果中看到的。

【讨论】:

谢谢!我了解 SUM() 可以增量工作,但 LAST_VALUE() 也可以增量工作?如果我想获取每个用户的最后状态,最好的方法是什么? 好的。我想现在我理解了这种行为。因此,当您在没有窗口框架子句的 OVER 子句中使用 ORDER BY 时,默认的窗口框架是 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW。这是正确的吗? 对于其他问题,请开始一个新问题 - 如果它回答了原始问题,请接受此答案。

以上是关于带有 ASC 的 LAST_VALUE() 和带有 DESC 的 FIRST_VALUE 返回不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

带有条件的休眠调用函数

MySQL 按多列组合排序(不是按 field1 asc、field2 asc 排序)

带有连字符的 Jquery tablesorter 数字

流利的验证允许空或带有结构的值

Jquery 数据表 - 单击标题时如何进行多列排序和重绘表,它可以是 asc 或 desc

带有Codeigniter中If条件的MySQL get_where