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 := πIDID >= 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 中复制“文本到列”任务? [复制]

如何将Python Dask Dataframes合并到列中?

SQL 查询为其他列中的每个唯一条目返回最高和最低

SQL2000数据库中合并两行相同条件的值到列中怎么操作?