是否可以模拟以下MySQL查询:
SELECT * FROM `tbl` ORDER BY `date` DESC LIMIT X, 10
(X是参数)
在MS Access中?
答案 0 :(得分:12)
虽然 Access / JET TOP
关键字不能直接提供OFFSET
功能,但我们可以使用TOP
的聪明组合,子查询和“派生表”以获得相同的结果。
以下是在ORDER BY
名称和 ID 的人表中从偏移20开始获取10行的示例...
SELECT Person.*
FROM Person
WHERE Person.Id In
(
SELECT TOP 10 A.Id
FROM [
SELECT TOP 30 Person.Name, Person.Id
FROM Person
ORDER BY Person.Name, Person.Id
]. AS A
ORDER BY A.Name DESC, A.Id DESC
)
ORDER BY Person.Name, Person.Id;
基本上,我们查询前30个,反转顺序,查询前10个,然后从表中选择匹配的行,再次按顺序排序。这应该是相当有效的,假设 Id 是PRIMARY KEY
,并且名称上有索引。可能需要名称上的特定覆盖索引, ID (而不是名称上的一个)以获得最佳性能,但我认为索引隐含地涵盖了PRIMARY KEY
。
答案 1 :(得分:3)
另一种方式 - 假设你想要一个名为table1的表中的1000到1999记录(当然如果你有那么多记录)你可以做这样的事情。
MSSQL
SELECT *
FROM table1 LIMIT 1000, 1999;
MS Access
SELECT TOP 1000 *
FROM table1
Where ID NOT IN (SELECT TOP 999 table1.ID FROM table1);
要打破这个
SELECT TOP NumA *
FROM table1
Where ID NOT IN (SELECT TOP NumB table1.ID FROM table1);
UpperLimit = 1999
LowerLimit = 1000
NumA = UpperLimit - LowerLimit + 1
离。 1000 = 1999 - 1000 + 1
NumB = LowerLimit -1
离。 999 = 1000 - 1
答案 2 :(得分:1)
更好的查询是:
SELECT Users.*
FROM Users
WHERE Users.id In
(
SELECT TOP X A.id
FROM [
SELECT TOP Y Users.*
FROM Users
ORDER BY Users.reg_date DESC
]. AS A
ORDER BY A.reg_date ASC
)
ORDER BY Users.reg_date DESC
其中
if((totalrows - offset) < limit) then
X = (totalrows - offset)
else
X = limit
和
Y = limit + offset
例如,如果 total_rows = 12,我们将限制设置为 10 (每页显示10个用户),并且< strong>偏移量计算为 p * limit - (限制),其中 p 是当前页面的编号,因此在第一页( p = 1 )我们将得到: X = 12 和 Y = 10 ,第二个 X = 2 和 Y = 20 。用户列表按注册日期(降序)排序。
答案 3 :(得分:0)
简单快速的解决方案。
myTable {ID *,Field2,Filed3 ...}
假设您的SortOrder仅包含主键
SELECT TOP PageItemsCount tb01.*
FROM myTable AS tb01
LEFT JOIN (
SELECT TOP OffsetValue ID FROM myTable ORDER BY ID ASC
) AS tb02
ON tb01.ID = tb02.ID
WHERE ISNULL(tb02.ID)
ORDER BY tb01.ID ASC
例如,myTable
+-------+--------+--------+
| ID | Field2 | Filed3 |
+-------+--------+--------+
| 1 | a1 | b |
| 2 | a | b2 |
| 3 | a1 | b2 |
| 4 | a1 | b |
+-------+--------+--------+
SELECT TOP 2 * From myTable ORDER BY FIELD2;
+-------+--------+--------+
| ID | Field2 | Filed3 |
+-------+--------+--------+
| 2 | a | b2 |
| 4 | a1 | b |
| 3 | a1 | b2 |
| 1 | a1 | b |
+-------+--------+--------+
SELECT TOP 2 * From myTable ORDER BY FIELD2, FIELD3;
+-------+--------+--------+
| ID | Field2 | Filed3 |
+-------+--------+--------+
| 2 | a | b2 |
| 4 | a1 | b |
| 1 | a1 | b |
+-------+--------+--------+
但是,如果我们将ID添加到排序顺序[最后的字段列表]
SELECT TOP 2 * From myTable ORDER BY FIELD2, ID;
+-------+--------+--------+
| ID | Field2 | Filed3 |
+-------+--------+--------+
| 2 | a | b2 |
| 1 | a1 | b |
+-------+--------+--------+
最终请求
SELECT TOP PageItemsCount tb01.*
FROM myTable AS tb01
LEFT JOIN (
SELECT TOP OffsetValue ID FROM myTable ORDER BY Field2 ASC, ID
) AS tb02
ON tb01.ID = tb02.ID
WHERE ISNULL(tb02.ID)
ORDER BY tb01.Field2 ASC, tb01.ID
答案 4 :(得分:-1)
不,JET SQL没有直接的等价物。作为一种变通方法,您可以添加一个WHERE
子句,用于选择两个值之间的有序/ id列。
如果可能,您还可以对现有的MySQL /其他数据库使用传递查询。
虽然MS-Access中的TOP
可以限制返回的记录,但它不会像MySQL LIMIT
关键字一样使用两个参数(请参阅this question)。
答案 5 :(得分:-1)
你绝对可以使用top关键字获得“Limit”的等价物。请参阅:
Access Database LIMIT keyword