SQL - 如何找到列中的最高数字?
Posted
技术标签:
【中文标题】SQL - 如何找到列中的最高数字?【英文标题】:SQL - How to find the highest number in a column? 【发布时间】:2010-12-05 13:12:25 【问题描述】:假设我在客户表中有以下数据:(仅此而已)
ID FirstName LastName
-------------------------------
20 John Mackenzie
21 Ted Green
22 Marcy Nate
什么样的SELECT
语句可以让我得到ID 列中的数字22?
我需要做这样的事情来生成一个唯一的 ID。当然我可以让系统通过自动增量来执行此操作,但是我将如何获取自动生成的 ID?
我想到了SELECT ID FROM Customers
并计算返回的行数,但这似乎非常低效,在这种情况下,它会错误地返回“3”,尽管我需要一个唯一的 ID 23。
【问题讨论】:
好点,但他们的回答并没有直接回答我的问题。无论如何,我的方法是最安全的,因为我得到了一个免费的 ID,然后添加了一条记录。当然,您可以说并发操作可能会因为多个程序获得相同的“免费”ID 并重用它而搞砸……但这可以通过在获得免费 ID 后快速添加记录来防止。 msaeed 和其他一些人完全正确地回答了您的问题。问题是“”和“什么样的 SELECT 语句可以让我在 ID 列中获得数字 22?”。更正您的帖子,让您的意图更加明确。 不。我什至没有在谈论那些答案,只有 rexem 指出的那些。其他答案谈到插入 THEN 获取 ID,这显然不是我要求的。我要求的是 22(最大数量),而不是 23(最近填充的 ID)。 @Jeremy:不,正如 Brisbe42 解释的那样,您的方法是不安全的,因为可以将数据库隔离级别设置为允许在 INSERT/UPDATE 提交之前读取数据。如果您在尝试插入非唯一主键时遇到错误,希望您记住这个问题。 @Jeremy,依赖你的“超级快速”方法是不明智的。程序本质上应该是确定性的,否则它们可能是不正确的。您所做的就是将 A 从您的 ACID 原则中丢弃。如果您正在运行单用户数据库应用程序,那很好。 其他所有情况都应该使用原子操作。 【参考方案1】:你可以的
SELECT MAX(ID) FROM Customers;
【讨论】:
【参考方案2】:如果您刚刚将一条记录插入到客户表中并且需要最近填充的 ID 字段的值,则可以使用 SCOPE_IDENTITY
函数。这仅在 INSERT
与对 SCOPE_IDENTITY
的调用发生在同一范围内时才有用。
INSERT INTO Customers(ID, FirstName, LastName)
Values
(23, 'Bob', 'Smith')
SET @mostRecentId = SCOPE_IDENTITY()
这对您可能有用也可能没用,但要注意这是一个很好的技巧。它也适用于自动生成的列。
【讨论】:
【参考方案3】:SELECT * FROM Customers ORDER BY ID DESC LIMIT 1
然后获取 ID。
【讨论】:
【参考方案4】:select max(id) from customers
【讨论】:
【参考方案5】:要随时获取,可以SELECT MAX(Id) FROM Customers
。
但是,在您添加它的过程中,您也可以使用SCOPE_IDENTITY
-- 来获取该过程最后添加的 id。
这样更安全,因为它可以保证您得到您的Id
——以防其他人同时被添加到数据库中。
【讨论】:
【参考方案6】:如果您说的是 MS SQL,这是最有效的方法。这会根据标识的任何列从表中检索当前标识种子。
select IDENT_CURRENT('TableName') as LastIdentity
使用MAX(id)
更通用,但例如我有一个包含 4 亿行的表,需要 2 分钟才能获得MAX(id)
。 IDENT_CURRENT
几乎是瞬间...
【讨论】:
我必须记住这一点。好东西。 真的吗? 2分钟?你有id的索引吗?即使有 4 亿行,也应该几乎可以立即找到最小值或最大值。 它是“身份”上的非唯一、非聚集索引......不确定这是否是应用程序的正确设计,但它就是这样。 SQL 2005 Enterprise 也带有分区方案【参考方案7】:select max(id) from Customers
【讨论】:
【参考方案8】:如果您使用的是AUTOINCREMENT
,请使用:
SELECT LAST\_INSERT\_ID();
假设你使用的是 mysql: http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html
Postgres 通过 currval(sequence_name)
函数类似地处理这个问题。
请注意,使用MAX(ID)
是不安全的,除非您锁定表,因为可能(在简化的情况下)在您调用MAX(ID)
之前发生另一个插入并且您丢失了第一个插入的ID。上面的函数是基于会话的,所以如果另一个会话插入,你仍然会得到你插入的 ID。
【讨论】:
将插入与子选择一起使用可以使 max(id) 安全,请参阅我的答案。但是,老实说,如果自动增量可用并且您太担心可移植性,那么自动增量是一个更好的选择。【参考方案9】:如果您不使用自动递增字段,则可以通过以下方式获得类似的结果:
insert into Customers (ID, FirstName, LastName)
select max(ID)+1, 'Barack', 'Obama' from Customers;
这将确保在您提取最大 ID 和插入新记录之间不会出现其他人插入表中而导致的竞争条件。
这是使用标准 SQL,毫无疑问有更好的方法可以使用特定的 DBMS 来实现它,但它们不一定是可移植的(我们在商店中非常重视这一点)。
【讨论】:
【参考方案10】:您也可以使用关系代数。过程有点冗长,但这里只是为了了解 MAX() 的工作原理:
E := πID (Table_Name) E1 := πID (σID >= ID' ((ρID' E) ⋈ E)) – πID (σID ((ρID' E) ⋈ E))
你的答案: Table_Name ⋈ E1
基本上你所做的是从 A 中减去 a<
b 的有序关系集(a,b),其中 a,b ∈ A。
关系代数符号见: Relational algebra From Wikipedia
【讨论】:
我认为关系代数解决方案不会受到 SQL 问题的欢迎。【参考方案11】:下面是我制作下一个 ID 的方法:
INSERT INTO table_name (
ID,
FIRSTNAME,
SURNAME)
VALUES (((
SELECT COALESCE(MAX(B.ID)+1,1) AS NEXTID
FROM table_name B
)), John2, Smith2);
这样可以确保即使表 ID 为 NULL,它仍然可以正常工作。
【讨论】:
【参考方案12】:取决于您使用的 SQL 实现。例如,MySQL 和 SQLite 都有获取最后插入 id 的方法。事实上,如果你使用的是 php,甚至还有一个非常棒的函数来对应 mysql_insert_id()。
您可能应该考虑使用这个 MySQL 功能,而不是仅仅为了获得最大的插入 ID 而查看所有行。如果您的表变大,那可能会变得非常低效。
【讨论】:
【参考方案13】:如果您只想选择id
,请使用select max(id) from customer
。
如果要选择整行,请使用如下查询:
select c1.*
from customer c1, (select max(id) as max_id from customer )c2
where c1.id=c2.max_id
c2
是包含max id
的新临时表的别名。然后将其叉积与客户表一起获取以获取整行。
这里我们在 from 子句中编写查询,这通常非常有用。
【讨论】:
【参考方案14】:为了找到下一个(仍未使用的)自动增量,我使用这个功能已经有几年了。
public function getNewAI($table)
$newAI = false;
$mysqli = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);
if(mysqli_connect_errno())
echo "Failed to connect to MySQL: " . mysqli_connect_error();
$sql = "SHOW TABLE STATUS LIKE '".$table."'";
$result = $mysqli->query($sql);
if($result)
$row = $result->fetch_assoc();
$newAI = $row['Auto_increment'];
$mysqli->close();
return $newAI;
【讨论】:
【参考方案15】:select * from tablename order by ID DESC
这将为您提供 id 为 22 的行
【讨论】:
这将返回所有行;正确的位于结果集的“顶部”。它不会只返回具有最大 id 的行。【参考方案16】:在 PHP 中:
$sql = mysql_query("select id from customers order by id desc");
$rs = mysql_fetch_array($sql);
if ( !$rs ) $newid = 1; else $newid = $rs[newid]+1;
因此 $newid = 23
如果列 id 中的最后一条记录是 22。
【讨论】:
这是一个关于SQL的问题。以上是关于SQL - 如何找到列中的最高数字?的主要内容,如果未能解决你的问题,请参考以下文章
循环遍历范围,如果单元格包含值,则复制到列中的下一个空单元格
Google BigQuery SQL:从 JSON(列表和数组)中提取数据到列中
我有一个大型 CSV 文件,其中包含单个列中的信息。如何使用 python 在 excel 中复制“文本到列”任务? [复制]