Table rows in SQLite are stored in a BTree structure where the "key" is the rowid. As far as I can tell, the SQLite engine does an inorder traversal of the tree when doing a table scan (ie, from lowest to highest) returning rows in rowid order. The rowid is always the primary key of a table. All other keys that are not explicitly named rowid (<name> INTEGER PRIMARY KEY) are merely additional indexes where the key is the concatenation of the key columns plus the rowid of the table row. Thus a table with a non-INTEGER primary key (or a compound primary key declaration) is exactly the same as a unique index on the columns, or just an additional index.
While this is presently how SQLite works, it may not always be so. It is possible that a future version may change the order of traversal. In particular, I believe SQLite4 will not perform tablescan operations in rowid, but rather in storage order. Therefore, at present, if you use the negative timestamp as the key, the traversal order will be from newest record to oldest since the "lowest" rowid will be the most recent timestamp. If you change the step function to update the final return value for each non-null value, you will return the "last" non-null value rather than the "first" -- where first and last means "numerically least" and "numerically greatest" rowid respectively. Of course, this is programming to an internal implementation detail. It may not be transportable to any other database system, and the specific implementation may change at any time. --- () ascii ribbon campaign against html e-mail /\ www.asciiribbon.org > -----Original Message----- > From: sqlite-users-boun...@sqlite.org [mailto:sqlite-users- > boun...@sqlite.org] On Behalf Of Steinar Midtskogen > Sent: Friday, 19 October, 2012 15:43 > To: General Discussion of SQLite Database > Subject: Re: [sqlite] Find first non-NULL values of several columns > > "Keith Medcalf" <kmedc...@dessus.com> writes: > > > Alternatively, to implement your original question, write an aggregate > function which returns the first non-null value it comes across, and use the > negated unix timestamp as an explicit rowid, depending on the fact that a > table-scan does an in-order traversal of the table btree: > > Except for the names, the below code is *exactly*, character by > character, as what I first wrote, but then I realised that the order > of the values going to the step function might not be defined. So can > I trust that I will get the order of my unix time primary key? It > would be convenient if I can omit the timestamp argument in the > function. > > > > > typedef struct fnnCtx fnnCtx; > > struct fnnCtx > > { > > double fnn; > > int flag; > > }; > > > > SQLITE_PRIVATE void fnnStep(sqlite3_context *context, int argc, > sqlite3_value **argv) > > { > > fnnCtx* p = sqlite3_aggregate_context(context, sizeof(fnnCtx)); > > if (p && sqlite3_value_numeric_type(argv[0]) != SQLITE_NULL && p->flag > == 0) > > { > > p->fnn = sqlite3_value_double(argv[0]); > > p->flag = 1; > > } > > } > > > > SQLITE_PRIVATE void fnnFinal(sqlite3_context *context) > > { > > fnnCtx* p = sqlite3_aggregate_context(context, 0); > > if (p && p->flag == 1) > > sqlite3_result_double(context, p->fnn); > > } > > -- > Steinar Midtskogen > _______________________________________________ > sqlite-users mailing list > sqlite-users@sqlite.org > http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users _______________________________________________ sqlite-users mailing list sqlite-users@sqlite.org http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users