This second one also has the advantage that I understand what's being
expressed! 🙂

This works perfectly, thank you! (and thank you to all others that replied).

I'm not sure I understand the indexing, though. The query plan without
indexes is:

0|0|0|SCAN TABLE x AS x1
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1
1|0|0|SEARCH TABLE x AS x2

If I subsequently CREATE INDEX b_c_index ON x (b, c):

0|0|0|SEARCH TABLE x AS x1 USING INDEX b_c_index (b=?)
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1
1|0|0|SEARCH TABLE x AS x2 USING INDEX b_c_index (b=? AND c=?)

So far so good. But if I additionally CREATE INDEX b_a_index ON x (b, a):

0|0|0|SEARCH TABLE x AS x1 USING INDEX b_a_index (b=?)
0|0|0|EXECUTE CORRELATED SCALAR SUBQUERY 1
1|0|0|SEARCH TABLE x AS x2 USING INDEX b_a_index (b=?)

I've not dropped the b_c_index. Why does the subquery no longer use it?

Thanks,
Hamish



On 3 April 2017 at 10:20, R Smith <rsm...@rsweb.co.za> wrote:
> Another option, if a is simple and a suitable index exists, is to simply get
> the max in a correlated subquery, so this should work faster even:
>
> SELECT c,d FROM x AS x1 WHERE b=1 AND a=(SELECT MAX(x2.a) FROM x AS x2 WHERE
> x2.b=x1.b AND x2.c=x1.c)
>
> This needs no grouping because the sub-query ensures it, unless a can have
> duplicate values for any one c value.
>
>
>
>
> On 2017/04/03 11:09 AM, R Smith wrote:
>>
>>
>>
>> On 2017/04/03 10:51 AM, Hamish Allan wrote:
>>>
>>> Ah. My purpose is to determine "d for the most recent c with b=1",
>>> with "most recent" being "largest a".
>>>
>>> My query had been working for this, but I'd only been adding
>>> monotonically increasing values for "a" in my tests. I just tried
>>> doing otherwise and found that I had been relying on an implementation
>>> detail.
>>>
>>> Is there any way I can perform this collation at query time, or do I
>>> need to do it programmatically later on?
>>
>>
>> WITH CLT(d,c,a) AS (
>>   SELECT d,c,a FROM x WHERE b = 1 GROUP BY c,a
>> ), CMX(c,mxa) AS (
>>   SELECT c, MAX(a) FROM CLT GROUP BY c
>> )
>> SELECT d
>>   FROM CLT
>>   JOIN CMX ON CMX.c = CLT.c AND CMX.mxa = CLT.a
>> ;
>>
>> Zero Order-by's
>>
>>
>>
>>>
>>> Thanks,
>>> Hamish
>>>
>>>
>>>
>>>
>>>
>>> On 3 April 2017 at 00:41, Keith Medcalf <kmedc...@dessus.com> wrote:
>>>>
>>>> What is the purpose of the ORDER BY?
>>>>
>>>> The value of a used for the order by is from some random row in the
>>>> grouping of c.  Are there relationships between a, b, c, d that you have 
>>>> not
>>>> documented nor told us about?
>>>>
>>>> In any case, your most efficient index is on (b, c).
>>>>
>>>> The order by is useless.
>>>>
>>>>> -----Original Message-----
>>>>> From: sqlite-users
>>>>> [mailto:sqlite-users-boun...@mailinglists.sqlite.org]
>>>>> On Behalf Of Hamish Allan
>>>>> Sent: Sunday, 2 April, 2017 17:28
>>>>> To: sqlite-users@mailinglists.sqlite.org
>>>>> Subject: [sqlite] Indexing WHERE with GROUP BY and ORDER BY
>>>>>
>>>>> Given a table:
>>>>>
>>>>> CREATE TABLE x (a INT, b INT, c TEXT, d TEXT);
>>>>>
>>>>> the query:
>>>>>
>>>>> SELECT d FROM x WHERE b = 1 GROUP BY c ORDER BY a;
>>>>>
>>>>> shows the following plan, without indexes:
>>>>>
>>>>> 0|0|0|SCAN TABLE x
>>>>> 0|0|0|USE TEMP B-TREE FOR GROUP BY
>>>>> 0|0|0|USE TEMP B-TREE FOR ORDER BY
>>>>>
>>>>> I can create an index to cover the WHERE clause:
>>>>>
>>>>> CREATE INDEX b_index ON x (b);
>>>>>
>>>>> which gives the plan:
>>>>>
>>>>> 0|0|0|SEARCH TABLE x USING INDEX b_index (b=?)
>>>>> 0|0|0|USE TEMP B-TREE FOR GROUP BY
>>>>> 0|0|0|USE TEMP B-TREE FOR ORDER BY
>>>>>
>>>>> or I can create an index to cover the GROUP BY clause:
>>>>>
>>>>> DROP INDEX b_index;
>>>>> CREATE INDEX c_index ON x (c);
>>>>>
>>>>> which gives the plan:
>>>>>
>>>>> 0|0|0|SCAN TABLE x USING INDEX c_index
>>>>> 0|0|0|USE TEMP B-TREE FOR ORDER BY
>>>>>
>>>>> but I don't seem to be able to create a combined index to cover both
>>>>> the WHERE and GROUP BY clauses (let alone the ORDER BY clause).
>>>>>
>>>>> Am I missing something, or is this just not possible?
>>>>>
>>>>> If it's not possible, which is the more efficient of those indexes  --
>>>>> or is there a third way, using an index for the ORDER BY, which would
>>>>> be more efficient still?
>>>>>
>>>>> Thanks,
>>>>> Hamish
>>>>> _______________________________________________
>>>>> 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
>>
>>
>> _______________________________________________
>> 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

Reply via email to