I need to display what the table contains from the freshest data to the oldest. Something like this doesn't work:
SELECT * FROM table ORDER BY DESC;. I know its becouse after ORDER BY should be name of the column. But I want to just reverse normal order (by normal I mean from the oldest to the freshest data). How to do this?
In your query the DESC stands for descending, the reverse is ascending, or:
SELECT * FROM table ORDER BY column ASC;
btw, if you do not specify a column, what you call "normal order" really is random unless you specify an ordering.
The "normal order" is not always from oldest to freshest, since some records may be deleted and then these are replaced with the new ones. It means that the "natural order" may appear to be somewhat "random" with the freshest items being in the middle of the dataset.
You need to add a column for an insertion date or an incrementing key.
You can't rely on the physical storage pattern to give you a correct ordering. According to the MySQL documentation, there is no guarantee that rows returned will be in any particular order.
"...the result rows are displayed in no
particular order. It is often easier
to examine query output when the rows
are sorted in some meaningful way. To
sort a result, use an ORDER BY clause."
http://dev.mysql.com/doc/refman/5.0/en/sorting-rows.html
You could create a new field of type timestamp and set the default value to CURRENT_TIMESTAMP, then then ORDER BY on that field.
The physical ordering of the records in a table are not guaranteed to match the sequence in which they were created. To do this, you will need to find or create a field you can sort on. A 'create date' field, or perhaps an id value which increases as new records are added (like an order id or something).
if you have autoincremented ID's , so maybe
order by id desc ? :)
Related
I have a column named id in my SQLite database which is auto-increment, Primary Key, Unique.
Is the result of the following query guaranteed to be the smallest value of id in the database and does this correspond to the "oldest" (as in a FIFO) row to be inserted?
SELECT id FROM table LIMIT 1
The SQLite documentation is quite explicit:
If a SELECT statement that returns more than one row does not have an
ORDER BY clause, the order in which the rows are returned is
undefined. Or, if a SELECT statement does have an ORDER BY clause,
then the list of expressions attached to the ORDER BY determine the
order in which rows are returned to the user.
The LIMIT is applied after an ORDER BY would be, so I don't think it affects the application of this statement.
Hence, if you want the first row, use ORDER BY:
SELECT id
FROM table
ORDER BY id
LIMIT 1;
Note that if id is a primary key, this will add basically no overhead.
I should emphasize that in practice you are probably going to get the smallest id without the ORDER BY. However, it is a really, really bad idea to depend on behavior that directly contradicts the documentation.
Is the result of the following query guaranteed to be the smallest value of id in the database
Yes. However if the table is empty or the id column is NULL, it could also return NULL
and does this correspond to the "oldest" (as in a FIFO) row to be inserted?
No, there's no guarantee of that.
I have a table that contains an 'id' column of type BIGSERIAL. I also have an index for this one column (sort order descending, BTREE, unique).
I often need to retrieve the last 10, 20, 30 entries from a table of millions of entries, like this:
SELECT * FROM table ORDER BY id DESC LIMIT 10
I would have thought it's a pretty clear case: there's an index for this particular field, sort order matches, and I need only 10 entries compared to millions in the whole table, this query definitely uses an index scan.
But it doesn't it does a sequential scan over the whole table.
I try to dig deeper, didn't find anything unusual. The Postgres doc at https://www.postgresql.org/docs/9.6/static/indexes-ordering.html says:
An important special case is ORDER BY in combination with LIMIT n: an
explicit sort will have to process all the data to identify the first
n rows, but if there is an index matching the ORDER BY, the first n
rows can be retrieved directly, without scanning the remainder at all.
But it still doesn't work. Does anybody have any pointers for me? Maybe I'm just not seeing the forrest for the trees anymore... :-(
Ok, saying it out loud and trying to gather more information to put into my question apparently made me see the forrest again, I found the actual problem. Further down in the doc I mentioned above is this sentence:
An index stored in ascending order with nulls first can satisfy either
ORDER BY x ASC NULLS FIRST or ORDER BY x DESC NULLS LAST depending on
which direction it is scanned in.
This was the problem. I specified the sort order in the index but I ignored the NULLS FIRST vs. LAST.
Postgres default is NULLS FIRST if you don't mention it explicitly in your query. So what Postgres found was the combination ORDER BY DESC NULLS FIRST which wasn't covered by my index. The combination of both SORT ORDER and NULLS is what matters.
The 2 possible solutions:
Either mention NULLS FIRST/LAST accordingly in the query so that it matches the index
...or change the index to NULLS FIRST (which is what I did)
Now Postgres is doing a proper index scan and only touches 10 elements during the query, not all of them.
If you need to get last 10 entries in table you can use this:
SELECT *
FROM table
WHERE id >= (SELECT MAX(id) FROM table) - 10
ORDER BY id DESC
And similarly for 20 and 30 entries.
This looks not so clear, but works fast as long as you have index for 'id' column.
What is the query for the latest input in a database? ASC and DESC don't seem to work because I don't have a primary key.
What is the query for the latest input in a database.
By default there isn't.
Order isn't guaranteed in a relational database, it's specified by the SELECT query used to view the data. If you want to order by "most recent" then you need a field which stores that information. Something like a DateAdded field, for example. (Which can either be populated by the application or just given a default value of the current date so it automatically adds the value on every INSERT.) Then you'd simply order by that:
SELECT *
FROM SomeTable
ORDER BY DateAdded DESC
ASC and DESC don't seem to work
They do, you just need actual values by which to order the results of the query.
Every table will have primary key. Use that key to get the latest entry.
SELECT * FROM mytable ORDER BY id DESC LIMIT 1
Share your columns name. That might help to resolve your query.
While trying to implement pagination from server side in postgres, i came across a point that while using limit and offset keywords you have to provide an ORDER BY clause on a unique column probably the primary key.
In my case i am using the UUID generation for Pkeys so I can't rely on a sequential order of increasing keys. ORDER BY pkey DESC - might not result in newer rows on top always.
So i resorted to using Created Date column - timestamp column which should be unique.
But my question comes what if the UI client wants to sort by some other column? in the event that it might not always be a unique column i resort to ORDER BY user_column, created_dt DESC so as to maintain predictable results for postgres pagination.
is this the right approach? i am not sure if i am going the right way. please advise.
I talked about this exact problem on an old blog post (in the context of using an ORM):
One last note about using sorting and paging in conjunction. A query
that implements paging can have odd results if the ORDER BY clause
does not include a field that represents an empirical sequence in the
data; sort order is not guaranteed beyond what is explicitly specified
in the ORDER BY clause in most (maybe all) database engines. An
example: if you have 100 orders that all occurred on the exact same
date, and you ask for the first page of this data sorted by this date,
then ask for the second page of data sorted the same way, it is
entirely possible that you will get some of the data duplicated across
both pages. So depending on the query and the distribution of data
that is “sortable,” it can be a good practice to always include a
unique field (like a primary key) as the final field in a sort clause
if you are implementing paging.
http://psandler.wordpress.com/2009/11/20/dynamic-search-objects-part-5sorting/
The strategy of using a column that uniquely identifies a record as pkey or insertion_date may not be possible in some cases.
I have an application where the user sets up his own grid query then it can simply put any column from multiple tables and perhaps none is a unique identifier.
In a case that can be useful you use rownum. You simply select the rownum and use his sort in over function. It would be something like:
select col1, col2, col3, row_number() over(order by col3) from tableX order by col3
It's important that over(order by *) match with order by *. Thus your paging will have consistent results every time.
i've got an issue due to database conception.
My data are grouped in a table which looks like :
IdGroup | IdValue
So for each group i've got the list of value.
Indeed, we should have had an order column or an id, but i can't.
Do you know anyway which can prove the order of the select value based on the insert order ?
I mean, if I inserted 1003,1001,1002 could i garantuee it to be retrieve in this order ?
IdGroup | IdValue
1 | 1003
1 | 1001
1 | 1002
Of course, using an order by doesn't seems to fit because i don't have any column usable.
Any idea ? Using a system proc or something like this.
Thanks a lot :)
Stop telling me to use an order by and altering the table, it doesn't fit and yes i know it's the good pratice to do... thanks :)
A couple of ideas:
DBCC PAGE (undocumented) can be used to look at the raw data pages of the table. It may be possible to determine insert order by looking at the low level information.
If you cannot alter the table, can you add a table to the database? If so, consider creating a table with an identity column and use a trigger on the original table to insert the records in the new table.
Also, you should include which version(s) of SQL Server are involved. Doing anything this unusual will very often be version specific.
You shouldn't rely on the data being returned in a particular order; use an ORDER BY clause to guarantee the order.
(Despite the fact that data appears to be returned in clustered index order, this might not always be the case).
Whilst some small scale tests will show that it returns it in what appears to be the right order, it just will not hold.
The golden rule remains - unless an order by clause is specified, there are no guarentees provided on the order of the returned data.
edit : If you place a non-clustered index on the idgroup column it is forced to add a hidden field, the uniqueifier since the values are the same - the problem it, you can't access it in an order by clause, but from a forensic perspective, you can determine the order it was inserted in.
As others have said, the only way to guarantee an ordering is with an ORDER BY clause. What isn't highlighted in their answers is that, the only place that this ORDER BY matters is in the SELECT statement. It doesn't* matter if you apply an ORDER BY clause during the INSERT statement; the system is free to return results from a select in whatever order it finds most efficient, unless an ORDER BY is specified at that time.
*There's a particular way to ensure what order IDENTITY values are assigned to a result set during an INSERT, using an ORDER BY, but I can't remember the exact details, and it still doesn't effect the order of SELECT.
Can you add the Created Date column? In this way you can get the records using Order by Clause Created Date. Moreover set it's default value Getdate()