#sql #postgresql #pagination #database-cursor
#sql #postgresql #разбивка на страницы #база данных-курсор
Вопрос:
Это очень, очень новичковый и глупый вопрос, но, похоже, я не могу найти, что означает следующее в 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)
означает? что это сравнивает? изменение второго значения, похоже, по какой-то причине не влияет на результаты.
Ответ №1:
При сравнении кортежей используется лексиографический порядок, что означает, что второе значение используется только в случае, если первое значение связано.
Итак, если ваша строка имеет временную метку точно такого значения отсечки, то идентификатор должен быть больше 0.
Догадка: это используется для подкачки страниц на основе курсора, где вторая страница начинается сразу после последнего значения на первой странице (в соответствии с критериями сортировки, здесь временная метка), с идентификатором, используемым в качестве связующего звена (для случаев, когда последняя запись на предыдущей странице и первая запись на следующей странице имеют одинаковое значение сортировки — вероятно, маловероятно для временных меток, но очень вероятно, если вы заказываете по зарплате или тому подобное).
Комментарии:
1. да, вы правы, это используется для подкачки на основе курсора. спасибо за ответ. Выбор этого в качестве ответа из-за предположения о курсоре в моем случае. Однако другие ответы верны.
Ответ №2:
Это сравнение записей вместе.
Запись A строго больше, чем другая B, если крайнее левое поле A строго больше, чем крайнее левое поле B или, если они равны, если 2-е поле A строго больше, чем 2-е поле B или, если эти поля секунд равны друг другу, если 3-е поле A строго больше, чем 3-е поле 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'
- если
last_updated = '2019-03-28 23:30:22.496 00:00'
, то сравните во 2-м поле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)
Ответ №3:
Значения в скобках представляют собой строки. Из точного руководства:
4.2.13. Конструкторы строк
Конструктор строк — это выражение, которое создает значение строки (также называемое составным значением), используя значения для своих полей-членов. Конструктор строк состоит из ключевого слова
ROW
, левой круглой скобки, нуля или более выражений (разделенных запятыми) для значений поля строки и, наконец, правой круглой скобки. Например:SELECT ROW(1,2.5,'this is a test');
Ключевое слово
ROW
необязательно, если в списке более одного выражения.
И затем немного ниже:
Кроме того, можно сравнить значения двух строк или проверить строку с НУЛЕВЫМ или НЕ НУЛЕВЫМ значением, например:
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
Таким образом, две строки сравниваются поэлементно с помощью <
.