where 子句括号中的逗号分隔值大于

where clause parentheses with comma separated values greater than

这是一个非常非常愚蠢的问题,但我似乎无法在 Postgres 中找到以下含义:

select * 
from table 
where (last_updated, id) > (timestamp with time zone '2019-03-28 23:30:22.496+00:00', 0)

基本上 (last_updated, id) > (timestamp with time zone '2019-03-28 23:30:22.496+00:00', 0) 是什么意思?它在比较什么?由于某些原因,更改第二个值似乎对结果没有影响。

这是一起比较记录。

如果 A 的最左边字段严格大于 B 的最左边字段,或者如果它们相等,如果 A 的第二个字段严格大于 B 的第二个字段,则记录 A 严格大于另一个 B或者,如果这些秒字段彼此相等,如果 A 的第三个字段严格大于 B 的第三个字段或者......它可以继续对超过 2 个或 3 个字段进行比较

因此,(last_updated, id) > (timestamp with time zone '2019-03-28 23:30:22.496+00:00', 0) 等同于:

  1. 比较第一个字段:last_updated > '2019-03-28 23:30:22.496+00:00'
  2. if last_updated = '2019-03-28 23:30:22.496+00:00' then compare on the 2nd field id > 0

或者如果我把它放在一个布尔表达式中:

`last_updated > '2019-03-28 23:30:22.496+00:00'`
OR (
    last_updated = '2019-03-28 23:30:22.496+00:00'
    AND id > 0
)

如您所见,其他语法要短得多。


PS:在 postgreSQL 中,至少版本 11,您可以使用这种比较来进行非常好的查找​​,例如:

SELECT *
FROM A
WHERE (field1, field2, field3) IN (SELECT field1, field2, field3 FROM B)

括号内的值为行。来自 fine manual:

4.2.13. Row Constructors

A row constructor is an expression that builds a row value (also called a composite value) using values for its member fields. A row constructor consists of the key word ROW, a left parenthesis, zero or more expressions (separated by commas) for the row field values, and finally a right parenthesis. For example:

SELECT ROW(1,2.5,'this is a test');

The key word ROW is optional when there is more than one expression in the list.

然后再往下一点:

Also, it is possible to compare two row values or test a row with IS NULL or IS NOT NULL, for example:

SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same');

SELECT ROW(table.*) IS NULL FROM table;  -- detect all-null rows

因此这两行使用<逐个元素进行比较。

比较元组使用词法顺序,这意味着第二个值仅在第一个值相同的情况下使用。

因此,如果您的行的时间戳恰好是该截止值,则 ID 需要大于 0。

预感:这用于基于游标的分页,其中第二页在第一页的最后一个值之后开始(根据排序标准,此处为时间戳),id 用作绑定-断路器(当上一页的最后一个条目和下一页的第一个条目具有相同的排序值时——时间戳可能不太可能,但如果你按薪水等排序则很有可能)。