You can think of it this way.
SELECT TOP N without ORDER BY returns several rows of N , neither the first nor the last, only some. Which rows that it returns are not defined. You can run the same statement 10 times and get 10 different sets of lines each time.
So, if the server had the SELECT LAST N syntax, then the result of this statement without ORDER BY would again be undefined, which is exactly what you get with the existing SELECT TOP N without ORDER BY .
You emphasized in your question that you know and understand what I wrote below, but I will still keep it clear to everyone who reads this later.
Your first phrase in the question
The SQL server now has SELECT TOP N ... , in which we can get the first n rows in ascending order (default), cool.
wrong. With SELECT TOP N without ORDER BY you get N "random" rows. Well, not very random, the server does not randomly jump from line to line purposefully. He chooses a specific deterministic method of scanning through the table, but there can be many different ways to scan the table, and the server can freely change the selected path whenever he wants. This means "undefined".
The server does not track the order in which the rows were inserted into the table, so your assumption that the results of SELECT TOP N without ORDER BY determined by the order in which the rows were inserted into the table are incorrect.
So the answer to your last question
why there is no select last/bottom like it.
is an:
- without
ORDER BY SELECT LAST N results will be exactly the same as SELECT TOP N results - undefined. - with
ORDER BY result of SELECT LAST N ... ORDER BY X ASC exactly the same as the result of SELECT TOP N ... ORDER BY X DESC .
So, it makes no sense to have two keywords that do the same thing.
There is a good point in Peter's answer: the word TOP somewhat misleading. This really means that the LIMIT result is set to a number of lines.
By the way, with SQL Server 2012 they added support for the ANSI OFFSET standard:
OFFSET { integer_constant | offset_row_count_expression } { ROW | ROWS } [ FETCH { FIRST | NEXT } {integer_constant | fetch_row_count_expression } { ROW | ROWS } ONLY ]
When adding another keyword, it was justified that it is an ANSI AND standard, it adds important functionality - pagination, which did not exist before.
I would like to thank @ Razort4x here for providing a very good SELECT reference , cannot be guaranteed without an ORDER BY .
This concept is often misunderstood, and I saw many questions here about SO, which would be very helpful if they had a quote from this link.
The answer to your question
Why SQL Server does not have SELECT LAST or says SELECT BOTTOM or something like this, where we do not need to specify ORDER BY and that would give the last record inserted into the table at the time of the query (again, I will not go into details about whether this will be the result in the case of uncommitted readings or phantom).
:
The devil is in the details that you want to omit. In order to find out which record was the last inserted into the table at the time the query was executed (and in order to know this in a somewhat sequential / nonrandom way), the server needs to track this information in some way. Even if this is possible in all scenarios of several simultaneous transactions, it is most likely expensive in terms of performance. Not every SELECT requested this information (in fact, very little or not at all), but the overhead of tracking this information would always be there.
So you can think of it this way: by default, the server does nothing specific to know / track the order in which the rows were inserted, as this affects performance, but if you need to know that you can use, for example, the IDENTITY column . Microsoft could design the server mechanism so that an IDENTITY column is required in each table, but they made it optional, which, in my opinion, is good. I know better than a server which of my tables needs an IDENTITY column and which ones don't.
Summary
I would like to summarize that you can watch SELECT LAST without ORDER BY two different ways.
1) When you expect SELECT LAST to behave according to the existing SELECT TOP . In this case, the result is undefined for LAST and TOP , i.e. The result is virtually the same. In this case, it comes down to the (un) presence of another keyword. In this case, the developers of the language (T-SQL language) are always reluctant to add keywords, if there is no good reason for this. In this case, this can clearly be avoided.
2) If you expect SELECT LAST to behave like SELECT LAST INSERTED ROW . By the way, by the way, the same expectations expect SELECT TOP behave like SELECT FIRST INSERTED ROW or add new keywords LAST_INSERTED , FIRST_INSERTED to keep the existing TOP keyword intact. In this case, it comes down to performance and the added overhead of this behavior. The server currently avoids this performance penalty if you do not need this information. If you need it, IDENTITY is a pretty good solution if you use it carefully.