Thomas Steffen <[EMAIL PROTECTED]> writes: > On 4/14/05, [EMAIL PROTECTED] > <[EMAIL PROTECTED]> wrote: >> How about these: >> >> SELECT * from Mactor WHERE id = (SELECT MAX(id) FROM Mactor); >> SELECT * from Mactor WHERE id = (SELECT MIN(id) FROM Mactor); > > I am working on a similar problem at the moment, but unless I missed > something, ORDER BY id LIMIT 1 works fine for me. Is there any > benefit of one formulation against the other? Is the nested SELECT > less efficient? Or are they identical in bytecode?
EXPLAIN is your friend. As can be seen by EXPLAINing each query (see below), there are fewer instructions involved in the one with the subquery, and no sorts or loops as are done in the initial method. (Note that I've changed the maximum value to what fits in a signed 32-bit field since I'm doing this with 2.8.16. You could try a similar experiment with 3.0.x. Actually, it looks like you don't even need the WHERE clause in the original query, and I've tested that modification at the end of the EXPLAINation below, as well. > What if id is not unique, and I may have rows with identical id? The original poster had 'id' as INTEGER PRIMARY KEY so that wouldn't be possible. If it is possible, then you'd have to decide what you wanted to do with multiple results. % sqlite :memory: SQLite version 2.8.16 Enter ".help" for instructions sqlite> CREATE TABLE Mactor ...> ( ...> id INTEGER PRIMARY KEY, ...> name TEXT, ...> -- any other fields ...> comment TEXT ...> ); sqlite> explain SELECT * FROM Mactor WHERE id < 2147483647 ORDER BY id DESC LIMIT 1; addr|opcode|p1|p2|p3 0|ColumnName|0|0|id 1|ColumnName|1|0|name 2|ColumnName|2|1|comment 3|Integer|-1|0| 4|MemStore|0|1| 5|ColumnName|3|0|INTEGER 6|ColumnName|4|0|TEXT 7|ColumnName|5|0|TEXT 8|Integer|0|0| 9|OpenRead|0|3|Mactor 10|VerifyCookie|0|31| 11|Rewind|0|25| 12|Integer|2147483647|0|2147483647 13|MemStore|1|1| 14|Recno|0|0| 15|MemLoad|1|0| 16|Ge|0|25| 17|Recno|0|0| 18|Column|0|1| 19|Column|0|2| 20|SortMakeRec|3|0| 21|Recno|0|0| 22|SortMakeKey|1|0|- 23|SortPut|0|0| 24|Next|0|14| 25|Close|0|0| 26|Sort|0|0| 27|SortNext|0|32| 28|MemIncr|0|31| 29|SortCallback|3|0| 30|Goto|0|27| 31|Pop|1|0| 32|SortReset|0|0| 33|Halt|0|0| sqlite> explain SELECT * from Mactor WHERE id = (SELECT MAX(id) FROM Mactor); addr|opcode|p1|p2|p3 0|VerifyCookie|0|31| 1|Integer|0|0| 2|OpenRead|1|3|Mactor 3|Last|1|0| 4|Recno|1|0| 5|MemStore|0|1| 6|Goto|0|7| 7|Close|1|0| 8|ColumnName|0|0|id 9|ColumnName|1|0|name 10|ColumnName|2|1|comment 11|ColumnName|3|0|INTEGER 12|ColumnName|4|0|TEXT 13|ColumnName|5|0|TEXT 14|Integer|0|0| 15|OpenRead|0|3|Mactor 16|MemLoad|0|0| 17|MustBeInt|1|23| 18|NotExists|0|23| 19|Recno|0|0| 20|Column|0|1| 21|Column|0|2| 22|Callback|3|0| 23|Close|0|0| 24|Halt|0|0| sqlite>explain SELECT * FROM Mactor ORDER BY id DESC LIMIT 1; addr|opcode|p1|p2|p3 0|ColumnName|0|0|id 1|ColumnName|1|0|name 2|ColumnName|2|1|comment 3|Integer|-1|0| 4|MemStore|0|1| 5|ColumnName|3|0|INTEGER 6|ColumnName|4|0|TEXT 7|ColumnName|5|0|TEXT 8|Integer|0|0| 9|OpenRead|0|3|Mactor 10|VerifyCookie|0|31| 11|Rewind|0|20| 12|Recno|0|0| 13|Column|0|1| 14|Column|0|2| 15|SortMakeRec|3|0| 16|Recno|0|0| 17|SortMakeKey|1|0|- 18|SortPut|0|0| 19|Next|0|12| 20|Close|0|0| 21|Sort|0|0| 22|SortNext|0|27| 23|MemIncr|0|26| 24|SortCallback|3|0| 25|Goto|0|22| 26|Pop|1|0| 27|SortReset|0|0| 28|Halt|0|0| sqlite>