On 2016/03/10 8:37 PM, James K. Lowden wrote:
> On Thu, 10 Mar 2016 10:17:57 +0100
> Alberto Wu <blu at skylable.com> wrote:
>
>> On 03/09/16 23:30, James K. Lowden wrote:
>>>> SELECT P.id FROM (
>>>>        SELECT 0 AS sect, id FROM t WHERE id >= 'pen'
>>>>        UNION ALL
>>>> SELECT 1, id FROM t WHERE id < 'pen'
>>>> ) AS P
>>>> ORDER BY P.sect, P.id
>>>> ;
>>> This is the correct answer.
>> Hi,
>>
>> unfortunately the correct answer comes with an extra scan and a temp
>> b-tree so I'd rather keep the two queries split and handle the case
>> programmatically.
> Hmm, does this work any better?
>
>       SELECT id FROM t
>       ORDER BY id < 'pen' desc, id;

It works, but not better. I think it was Igor who proposed similar (if 
not, apologies) which of course produces the correct result, but cannot 
take advantage of the index on id so it becomes a result-set walk 
causing longer ordering of values - exactly what the OP tried to avoid.

I myself is sad to find that the SELECTs in between UNION ALL statements 
qualify as sub-selects and do not implicitly honor the order in which 
they are UINIONed - I had this wrong.

I do this kind of thing so often when filling a selection box for instance:
   SELECT 'None'
UNION ALL
   SELECT City FROM Countrylist WHERE Country = :1
UNION ALL
SELECT City FROM Countrylist WHERE Country <> :1 ORDER BY City

Which, as you can deduce, adds a 'None' to the option list, then the 
selected country's capital city, then the other cities in alphabetical 
order. I now think I need a more sophisticated method to ensure that 
output doesn't get mangled. If SQLite ever changes this behaviour, lots 
of things will break for me, but, that's life, I will start fixing them all.

Heh, assumptions... that'll teach me! :)
Ryan



Reply via email to