Re: [sqlite] MIN() and MAX() of set of row values

2018-03-31 Thread Wout Mertens
As a sidenote, I believe row values were added because of keyset pagination
https://use-the-index-luke.com/no-offset. I found them to not be actually
useful, so I thought I'd explain here. (copied from my comments on that
page (now no longer visible), slightly edited)


I ended up implementing this approach for sqlite since it has the
(a,b)<(x,y) operation now, but while doing so I realized that that
comparison is not a magical operation that uses the given fields to compare
them to the sort order of the query, but instead logically equivalent to
`(a < x OR (a = x AND b < y)`.

So if you are querying with `ORDER BY a ASC, b DESC`, you have to use `(a >
x OR (a = x AND b < y))`, since there is no way to express that with the
combined operator.

Just wanted to point that out since it surprised me, and since I (wrongly)
gleaned from your explanation that the combined operator is necessary to
implement keyset pagination.

I did some EXPLAINing of "cursor where clauses" and the shortest plans were
with clauses of the form:

a >= x AND (a != x OR (b <= y AND (b != y OR c > z))

(with ORDER BY a ASC, b DESC, c ASC and x, y, z the last-seen values)

A bit annoying to write but the idea is that the DB can scan a in index
order, then b if needed, then c if needed.

In fact, writing it that way gets me less instructions than when I use the
row values. Not sure if that translates in faster queries though.


On Fri, Mar 30, 2018 at 7:09 PM David Raymond 
wrote:

> https://www.sqlite.org/rowvalue.html section 2.1 for ordering.
>
>
> -Original Message-
> From: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org]
> On Behalf Of Simon Slavin
> Sent: Friday, March 30, 2018 1:06 PM
> To: SQLite mailing list
> Subject: Re: [sqlite] MIN() and MAX() of set of row values
>
> On 30 Mar 2018, at 6:04pm, Peter Da Silva 
> wrote:
>
> > On 3/30/18, 11:58 AM, "sqlite-users on behalf of Simon Slavin" <
> sqlite-users-boun...@mailinglists.sqlite.org on behalf of
> slav...@bigfraud.org> wrote:
> >> can think of to do it is to devise a metric to turn a pair (a, b) into
> one number.
> >
> > Problem is you can't uniquely order pairs of points. Is (1, 2) greater
> or lesser than (2, 1)?
>
> That's up to you.  That's why you are devising the metric.  Maybe the
> metric is just score == a + b .
>
> Simon.
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> ___
> sqlite-users mailing list
> sqlite-users@mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread David Raymond
https://www.sqlite.org/rowvalue.html section 2.1 for ordering.


-Original Message-
From: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] On 
Behalf Of Simon Slavin
Sent: Friday, March 30, 2018 1:06 PM
To: SQLite mailing list
Subject: Re: [sqlite] MIN() and MAX() of set of row values

On 30 Mar 2018, at 6:04pm, Peter Da Silva  wrote:

> On 3/30/18, 11:58 AM, "sqlite-users on behalf of Simon Slavin" 
>  slav...@bigfraud.org> wrote:
>> can think of to do it is to devise a metric to turn a pair (a, b) into one 
>> number.
> 
> Problem is you can't uniquely order pairs of points. Is (1, 2) greater or 
> lesser than (2, 1)?

That's up to you.  That's why you are devising the metric.  Maybe the metric is 
just score == a + b .

Simon.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Igor Tandetnik

On 3/30/2018 1:04 PM, Peter Da Silva wrote:

On 3/30/18, 11:58 AM, "sqlite-users on behalf of Simon Slavin" 
 wrote:

can think of to do it is to devise a metric to turn a pair (a, b) into one 
number.


Problem is you can't uniquely order pairs of points.


Yes you can.


Is (1, 2) greater or lesser than (2, 1)?


"select (1, 2) < (2, 1)" says lesser.

For further discussion, see 
https://www.sqlite.org/rowvalue.html#row_value_comparisons
--
Igor Tandetnik


___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread David Raymond
Why not something simpler, like

select * from T order by a, b limit 1; --for the min,

select * from T order by a desc, b desc limit 1; --for the max?

select (select a, b from T order by a, b limit 1) = (1, 2) as ok;


-Original Message-
From: sqlite-users [mailto:sqlite-users-boun...@mailinglists.sqlite.org] On 
Behalf Of Mark Brand
Sent: Friday, March 30, 2018 10:48 AM
To: SQLite mailing list
Subject: [sqlite] MIN() and MAX() of set of row values

Hi,

Row values make life easier in so many ways, but I was just wondering if 
there is (or should be or could be) a way to use aggregate MIN() and 
MAX() on a set of row values.

Mark

CREATE TABLE T (a, b);
INSERT INTO T (a, b) VALUES (1, 2), (1, 3), (2, 3);

SELECT MIN((a,b)) = (1, 2) ok  FROM T;
--Error: near line 4: row value misused

SELECT MIN((SELECT a, b)) = (1, 2) ok  FROM T;
--Error: near line 7: row value misused

SELECT (1, 2) = MIN(SELECT a, b FROM T);
--Error: near line 10: near "SELECT": syntax error

--ok
SELECT T.*
FROM T
LEFT JOIN T S
   ON (S.a, S.b) < (T.a, T.b)
WHERE S.a IS NULL;

--ok
SELECT (T.a, T.b) = (1, 2) ok
FROM T
LEFT JOIN T S
   ON (S.a, S.b) < (T.a, T.b)
WHERE S.a IS NULL;

___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Simon Slavin
On 30 Mar 2018, at 6:04pm, Peter Da Silva  wrote:

> On 3/30/18, 11:58 AM, "sqlite-users on behalf of Simon Slavin" 
>  slav...@bigfraud.org> wrote:
>> can think of to do it is to devise a metric to turn a pair (a, b) into one 
>> number.
> 
> Problem is you can't uniquely order pairs of points. Is (1, 2) greater or 
> lesser than (2, 1)?

That's up to you.  That's why you are devising the metric.  Maybe the metric is 
just score == a + b .

Simon.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Peter Da Silva
On 3/30/18, 11:58 AM, "sqlite-users on behalf of Simon Slavin" 
 wrote:
> can think of to do it is to devise a metric to turn a pair (a, b) into one 
> number.

Problem is you can't uniquely order pairs of points. Is (1, 2) greater or 
lesser than (2, 1)?

___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Simon Slavin
On 30 Mar 2018, at 5:55pm, Igor Tandetnik  wrote:

> I don't think that's what the OP had in mind. They didn't want the smaller of 
> a and b for each row, but rather the lexicographically smallest (a, b) pair 
> among all rows.
> 
> Row values support less-than comparison, so it kind of makes sense to expect 
> MIN to work on them, too.

Ah.  Okay, I get it.

The only way I can think of to do it is to devise a metric to turn a pair (a, 
b) into one number.

Simon.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Igor Tandetnik

On 3/30/2018 12:10 PM, Simon Slavin wrote:

On 30 Mar 2018, at 3:48pm, Mark Brand  wrote:


SELECT MIN((a,b)) = (1, 2) ok  FROM T;
--Error: near line 4: row value misused

SELECT MIN((SELECT a, b)) = (1, 2) ok  FROM T;
--Error: near line 7: row value misused

SELECT (1, 2) = MIN(SELECT a, b FROM T);
--Error: near line 10: near "SELECT": syntax error


You got very close to the right syntax.

SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> CREATE TABLE T (a, b);
sqlite> INSERT INTO T (a, b) VALUES (1, 2), (1, 3), (2, 3);
sqlite> SELECT min(a,b) FROM T;
1
1
2


I don't think that's what the OP had in mind. They didn't want the smaller of a 
and b for each row, but rather the lexicographically smallest (a, b) pair among 
all rows.

Row values support less-than comparison, so it kind of makes sense to expect 
MIN to work on them, too.
--
Igor Tandetnik


___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


Re: [sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Simon Slavin
On 30 Mar 2018, at 3:48pm, Mark Brand  wrote:

> SELECT MIN((a,b)) = (1, 2) ok  FROM T;
> --Error: near line 4: row value misused
> 
> SELECT MIN((SELECT a, b)) = (1, 2) ok  FROM T;
> --Error: near line 7: row value misused
> 
> SELECT (1, 2) = MIN(SELECT a, b FROM T);
> --Error: near line 10: near "SELECT": syntax error

You got very close to the right syntax.

SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> CREATE TABLE T (a, b);
sqlite> INSERT INTO T (a, b) VALUES (1, 2), (1, 3), (2, 3);
sqlite> SELECT min(a,b) FROM T;
1
1
2

Simon.
___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users


[sqlite] MIN() and MAX() of set of row values

2018-03-30 Thread Mark Brand

Hi,

Row values make life easier in so many ways, but I was just wondering if 
there is (or should be or could be) a way to use aggregate MIN() and 
MAX() on a set of row values.


Mark

CREATE TABLE T (a, b);
INSERT INTO T (a, b) VALUES (1, 2), (1, 3), (2, 3);

SELECT MIN((a,b)) = (1, 2) ok  FROM T;
--Error: near line 4: row value misused

SELECT MIN((SELECT a, b)) = (1, 2) ok  FROM T;
--Error: near line 7: row value misused

SELECT (1, 2) = MIN(SELECT a, b FROM T);
--Error: near line 10: near "SELECT": syntax error

--ok
SELECT T.*
FROM T
LEFT JOIN T S
  ON (S.a, S.b) < (T.a, T.b)
WHERE S.a IS NULL;

--ok
SELECT (T.a, T.b) = (1, 2) ok
FROM T
LEFT JOIN T S
  ON (S.a, S.b) < (T.a, T.b)
WHERE S.a IS NULL;

___
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users