круглые скобки предложения where со значениями, разделенными запятыми, превышающими

#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. Сравните по 1-му полю: last_updated > '2019-03-28 23:30:22.496 00:00'
  2. если 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
  

Таким образом, две строки сравниваются поэлементно с помощью < .