问题
I tried to get the the last and next row of my table by using this query:
SELECT TOP 1 Nummer FROM Empfänger WHERE Nummer < 4748 ORDER BY Nummer DESC
UNION
SELECT TOP 2 Nummer FROM Empfänger WHERE Nummer >= 4748 ORDER BY Nummer ASC;
The primary key “Nummer” is unique and auto-incremental , so there is
4747, 4748, 4749
It should imho return the above stated numbers, but instead it returns:
4747, 4798, 4799
When I open the Database with Access and set the filter "between" the values are shown correctly.
I changed the statement to:
SELECT DISTINCT TOP 1 Nummer FROM Empfänger WHERE Nummer < 4748 ORDER BY Nummer DESC
UNION
SELECT DISTINCT Nummer FROM Empfänger WHERE Nummer = 4748
UNION
SELECT DISTINCT TOP 1 Nummer FROM Empfänger WHERE Nummer > 4748 ORDER BY Nummer ASC;
This works nearly perfectly.
4747, 4748, 4750
When I write every statement in a single query it returns the right values...
SELECT DISTINCT TOP 1 Nummer FROM Empfänger WHERE Nummer < 4748 ORDER BY Nummer DESC
= 4747
SELECT DISTINCT Nummer FROM Empfänger WHERE Nummer = 4748
= 4748
SELECT DISTINCT TOP 1 Nummer FROM Empfänger WHERE Nummer > 4748 ORDER BY Nummer ASC;
= 4749
\
SELECT DISTINCT TOP 1 Nummer FROM Empfänger WHERE Nummer < 4750 ORDER BY Nummer DESC
UNION
SELECT DISTINCT Nummer FROM Empfänger WHERE Nummer = 4750
UNION
SELECT DISTINCT TOP 1 Nummer FROM Empfänger WHERE Nummer > 4750 ORDER BY Nummer ASC;
I checked it again, suddenly the above shown query worked. Thank you for your help.
回答1:
Access uses the JET engine. It seems that ORDER BY is applied AFTER the TOP clause and you will need to use subqueries of the form
select top n ...
from (
select ...
from table
where ...
order by ...
)
to get it to work.
回答2:
Yes, Access is not ANSI-92 compliant in this area whereas SQL-Server is, and SQL-Server can be made to mimic the non-compliant behavior of Access as an option. I discovered this in a situation where I have the option of adding the id field, which is PK, to the ORDER BY and thus working around the problem. As long as your solution causes at least one field's value in the multi-field ORDER BY to be different in successive records, your work-around will obey the TOP parameter. If your key does not break on at least one field, then you can think of the SELECT TOP being enforced in this surprisingly amateurish way:
"Return the TOP n records and look at the value of the nth record's ORDER BY field(s) and include all the additional records that have that(those) value(s)".
来源:https://stackoverflow.com/questions/13135347/sql-statement-returns-wrong-values-top-n-order-by