-1

我想检索最近添加的客户。我没有任何列来存储添加行的日期/时间,我的主键是Cust_ID,它不是一IDENTITY列,不一定按升序输入。

这是我的表,Customer假设已按此顺序添加了三行:

Cust_ID       Cust_Name      Cust_Age
-------------------------------------
2             C              23
6             A              25
3             B              22

在上面的示例中,我想获取最后一条记录 ( B)。SQL Server 中是否有任何预定义的函数将返回表的最后一行(不依赖于升序)?

4

5 回答 5

14

不,SQL Server 中没有预定义的函数会返回表的“最后一行”。

根据定义,表是一组无序的行。想象一下,你在一个袋子里扔了一堆弹珠。现在打开袋子,问别人哪个大理石最先或最后进入。现在把它们都扔在地板上,当其他人进入房间时,问他们哪个最先或最后一个落地。你不能这样做,因为没有额外的信息表明他们下降的顺序。

SQL Server 中的表也是如此。除非您添加 IDENTITY 列、日期时间列或触发器,或使用更改跟踪、CDC、审计等外部功能,否则 SQL Server 无法告诉您最后插入了哪一行。您可能认为仅从没有 order by 子句的表中进行选择看起来像是以正确的顺序返回数据,这纯属巧合。这是一个例子:

CREATE TABLE dbo.floobat
(
  ID INT PRIMARY KEY, 
  n VARCHAR(16), 
  x CHAR(4000) NOT NULL DEFAULT ''
);

INSERT dbo.floobat(ID,n) VALUES(1,'Sparky');
INSERT dbo.floobat(ID,n) VALUES(2,'Aaron');
INSERT dbo.floobat(ID,n) VALUES(3,'Norbert'); -- <-- inserted last

SELECT ID, n FROM dbo.floobat;

好的,所以默认情况下,这似乎没问题。结果:

ID    n
--    -------
1     Sparky
2     Aaron
3     Norbert -- < yes, this is right

但是,让我们更改您的应用程序或任何其他依赖于上述排序的表将不知道:

CREATE NONCLUSTERED INDEX x ON dbo.floobat(n);

SELECT ID, n FROM dbo.floobat;

哦哦!结果:

ID    n
--    -------
2     Aaron
3     Norbert
1     Sparky -- < oops, this is no longer right

您必须记住这一点:如果您不包含 ORDER BY 子句,您就是在告诉SQL Server 您不关心顺序。因此,它将找到返回数据的最有效方式,这可能会导致观察到的不同顺序。添加上面的索引为 SQL Server 检索数据提供了更好的访问路径。它仍然使用扫描,但该索引比聚集索引(只能在页面上容纳两行)更瘦。

Cust_ID即使没有索引,您也可能不会得到您期望的结果,因为您的列没有按升序插入这一事实令人费解。因此,如果您插入5and than 2,则在没有 ORDER BY 的情况下进行选择实际上会导致2then 5(假设不存在更好的索引)。

除了创建(或删除、更改或重建)索引之外的其他事情可能会导致排序行为发生相同类型的更改。应用服务包、CU 或修补程序;刷新过程缓存;使用各种重新编译选项;更新统计数据;重新启动服务器;添加或禁用跟踪标志;更改服务器选项选项;将数据库移动到不同的服务器;等等等等

因此,如果您想跟踪此信息,您需要以某种方式自己添加它,因为其他几个答案已经解决。

于 2013-11-14T17:00:10.943 回答
3

IDENTITY除非您的表中有任何一个或DateTime列,否则您无法插入最后一行。

于 2013-11-14T16:22:58.810 回答
3

如果您的表中没有可用的元数据,并且您无法编辑架构以提供时间戳或标识列,那么您应该依赖 SQL Server 的元数据生成机制。一是疾控中心

CDC 代表变更数据捕获,顾名思义,它可以帮助您了解已应用于数据的任何变更。我认为您可以使用此元数据来了解已插入表中的最新记录是什么。

于 2013-11-14T16:25:32.267 回答
2

如果您无法更改表架构,那么您可以考虑添加一个具有相同架构的新表,该表仅存储插入的最后一条记录,

于 2013-11-14T16:33:03.680 回答
2

任何一个

  • 添加时间戳

或者

  • 添加一个自动增量/标识键
于 2013-11-14T16:23:32.263 回答