基于Postgres文档偏移量是:
OFFSET表示在开始返回行之前跳过那么多行。
考虑到这一点,我想知道sql查询的默认排序/无排序逻辑是否对它有影响,使用默认排序时是否有机会使用相同的查询得到不同的结果?
答案 0 :(得分:1)
评论太长了。
OFFSET
和LIMIT
被用作查询处理的最后一步,实际上是从查询返回结果集时。
如果查询没有ORDER BY
,则查询结果采用 indeterminate 顺序。事实上,结果的排序可能会因查询的一次运行而异。
即使使用ORDER BY
,您也会获得不确定的订单 - 当行具有相同的键值时。 SQL中的排序不稳定(稳定排序总是以相同的顺序返回行)。原因很简单:SQL表代表无序集,因此没有"自然"命令定义一个稳定的排序。
如果您关心一致排序的数据,那么您应该始终使用ORDER BY
。而且,您应该确保键组合唯一地定义每一行。如果他们不这样做,请将主键作为ORDER BY
的最后一个键。
答案 1 :(得分:0)
对于默认情况下获得不同的结果(意味着没有顺序),确定这将基于SQL如何优化查询从1运行到另一个运行,但我猜想通常DML操作(如插入或删除)将是区分结果的最大罪魁祸首。
CREATE TABLE ExampleTable (Id INTEGER, Letter CHAR(1));
INSERT INTO ExampleTable (Id,Letter) VALUES (1,'A'),(5,'C'),(3,'B');
SELECT *
FROM
ExampleTable
ORDER BY 1
LIMIT 1 OFFSET 1
;
SELECT 'Example 1' as Example, *
FROM
ExampleTable
ORDER BY 1
LIMIT 1 OFFSET 1;
INSERT INTO ExampleTable (Id, Letter) VALUES (2,'D');
SELECT *
FROM
ExampleTable
ORDER BY 1
LIMIT 1 OFFSET 1
;
SELECT 'Example 1' as Example, *
FROM
ExampleTable
ORDER BY 1
LIMIT 1 OFFSET 1;
第一个结果是3,b
第二个结果是2,D
稍后当使用其他列运行时,我得到了5,c & 5,C
。当没有额外的专用值时,PostresSQL正在优化INTEGER上的查询。因此,这会导致默认(无顺序)与查询不同。 [http://rextester.com/YJKC24018]
现在考虑通过LETTER排序:
CREATE TABLE ExampleTable2 (Id INTEGER, Letter CHAR(1));
INSERT INTO ExampleTable2 (Id,Letter) VALUES (1,'A'),(3,'C'),(4,'D');
SELECT *
FROM
ExampleTable2
ORDER BY Letter
LIMIT 1 OFFSET 1
;
INSERT INTO ExampleTable2 (Id,Letter) VALUES (2,'B');
SELECT *
FROM
ExampleTable2
ORDER BY Letter
LIMIT 1 OFFSET 1
;
第一个结果为3,C
,但第二个结果为2,B
。因此,即使您选择了偏移量,因为记录集已更改,您可以获得相同的行或新行[http://rextester.com/IBI93830]
CREATE TABLE ExampleTable3 (Id INTEGER, Letter CHAR(1));
INSERT INTO ExampleTable3 (Id,Letter) VALUES (1,'A'),(3,'C'),(4,'D');
SELECT *
FROM
ExampleTable3
ORDER BY Letter
LIMIT 1 OFFSET 1
;
INSERT INTO ExampleTable3 (Id,Letter) VALUES (2,'B');
SELECT *
FROM
ExampleTable3
ORDER BY Letter
LIMIT 1 OFFSET 2
;
因此,这是一个示例,在您收到的最后一条记录(2,B)
之前插入了新记录(3,C)
。因此,即使您增加了OFFSET,您实际上也会再次获得相同的行(3,C)
。 [http://rextester.com/KRVIF54374]
CREATE TABLE ExampleTable4 (Id SERIAL, Letter CHAR(1));
INSERT INTO ExampleTable4 (Letter) VALUES ('A'),('C'),('D');
SELECT *
FROM
ExampleTable4
ORDER BY Id
LIMIT 1 OFFSET 1
;
INSERT INTO ExampleTable4 (Letter) VALUES ('B');
SELECT *
FROM
ExampleTable4
ORDER BY Id
LIMIT 1 OFFSET 1
;
DELETE FROM ExampleTable4 WHERE Letter = 'C';
SELECT *
FROM
ExampleTable4
ORDER BY Id
LIMIT 1 OFFSET 1
;
此示例显示ID上的顺序可以保持一致,除非在表上发生删除,现在结果已使用相同的查询进行了更改。 [http://rextester.com/LTN10302]