【问题标题】:SQL - How to find the highest number in a column?SQL - 如何找到列中的最高数字?
【发布时间】: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 和其他一些人完全正确地回答了您的问题。问题是“SQL - 如何找到列中的最高数字?”和“什么样的 SELECT 语句可以让我在 ID 列中获得数字 22?”。更正您的帖子,让您的意图更加明确。
  • 不。我什至没有在谈论那些答案,只有 rexem 指出的那些。其他答案谈到插入 THEN 获取 ID,这显然不是我要求的。我要求的是 22(最大数量),而不是 23(最近填充的 ID)。
  • @Jeremy:不,正如 Brisbe42 解释的那样,您的方法是安全的,因为可以将数据库隔离级别设置为允许在 INSERT/UPDATE 提交之前读取数据。如果您在尝试插入非唯一主键时遇到错误,希望您记住这个问题。
  • @Jeremy,依赖你的“超级快速”方法是不明智的。程序本质上应该是确定性的,否则它们可能是不正确的。您所做的就是将 A 从您的 ACID 原则中丢弃。如果您正在运行单用户数据库应用程序,那很好。 其他所有情况都应该使用原子操作。

标签: sql mysql sql-server


【解决方案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的问题。
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2014-12-31
                        • 2022-01-05
                        • 2019-10-10
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多