3

I am working on cursor based pagination using multiple columns. I need to make a tuple comparison since date might not be a unique value.

When I am using MySQL and PostgreSQL, I can do it like this.

WHERE (date, id) < (:date, :id) ORDER BY date DESC, id DESC

I can't do the same with Oracle and SQL Server. I am wondering how can I do a tuple comparison with those databases.

2
  • 1
    It would be helpful if you defined exactly what that operation means (particularly with null values if your columns are nullable). If you can define the logic, there are plenty of folks that can help you implement in SQL Server and/or Oracle. It may take longer for someone that also knows the exact definition in MySQL. Commented Oct 29, 2021 at 10:55
  • "cursor based pagination" do you mean "keyset pagination"? Commented Oct 31, 2021 at 11:28

1 Answer 1

3

Assuming that this MySQL documentation documents the behavior you want

For row comparisons, (a, b) <= (x, y) is equivalent to:

(a < x) OR ((a = x) AND (b <= y))

Then you should be able to write the query across all four platforms as

WHERE date < :date
   OR ((date = :date) and (id < :id)) 
ORDER BY date DESC, id DESC
5
  • Interestingly enough, this specific syntax is optimized on SQL Server when operating over an index (date, id) Commented Oct 31, 2021 at 11:29
  • 1
    @Charlieface So wouldn't it be better to avoid OR like: WHERE date <= ? AND NOT (date = ? AND id >= ?) ORDER BY date DESC, id DESC as suggested here? Commented Oct 31, 2021 at 16:26
  • @HasanCanSaral As I said, this particular case is optimized in SQL Server, you can see the execution plan in this fiddle dbfiddle.uk/… Commented Oct 31, 2021 at 16:42
  • I went with the @HasanCanSaral suggestion. In the link Hasan Can Saral shared, it suggest that MySQL is not optimized for tuple comparison but I believe that issue is fixed in my current MySQL version (5.7.35). Commented Nov 2, 2021 at 7:35
  • 1
    @HasanCanSaral The two-column version is optimized, but with three columns you need to normalize to have the ands at the top level - otherwise, it's not going to seek.
    – John
    Commented Aug 30, 2022 at 21:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.