SQL - Как найти наибольшее число в столбце? - PullRequest
45 голосов
/ 10 октября 2009

Допустим, у меня есть следующие данные в таблице «Клиенты»: (ничего более)

ID   FirstName   LastName
-------------------------------
20   John        Mackenzie
21   Ted         Green
22   Marcy       Nate

Какой оператор SELECT может получить число 22 в столбце идентификатора?

Мне нужно сделать что-то подобное, чтобы сгенерировать уникальный идентификатор. Конечно, я могу позволить системе делать это с помощью автоинкремента, но тогда как мне получить автоматически сгенерированный идентификатор?

Я подумал о «ВЫБЕРИТЕ ID ОТ ПОКУПАТЕЛЕЙ» и посчитал возвращенные строки, но это кажется ужасно неэффективным, и в этом случае он неправильно вернет «3», хотя мне нужен уникальный идентификатор 23.

Ответы [ 14 ]

103 голосов
/ 10 октября 2009

Вы можете сделать

SELECT MAX(ID) FROM Customers;
16 голосов
/ 10 октября 2009

Если вы только что вставили запись в таблицу Customers и вам нужно значение недавно заполненного поля ID, вы можете использовать функцию SCOPE_IDENTITY. Это полезно только тогда, когда INSERT произошел в той же области, что и вызов SCOPE_IDENTITY.

INSERT INTO Customers(ID, FirstName, LastName)
Values
(23, 'Bob', 'Smith')

SET @mostRecentId = SCOPE_IDENTITY()

Это может или не может быть полезным для вас, но это хорошая техника, чтобы знать. Он также будет работать с автоматически генерируемыми столбцами.

10 голосов
/ 17 октября 2012
SELECT * FROM Customers ORDER BY ID DESC LIMIT 1

Тогда получите ID.

8 голосов
/ 10 октября 2009

Чтобы получить его в любое время, вы можете сделать SELECT MAX(Id) FROM Customers.

В процедуре, в которую вы ее добавляете, вы также можете использовать SCOPE_IDENTITY - чтобы получить последний добавленный идентификатор этой процедуры. Это безопаснее, потому что это гарантирует, что вы получите свой Id - на тот случай, если другие будут добавлены в базу данных одновременно.

8 голосов
/ 10 октября 2009
select max(id) from customers
7 голосов
/ 10 октября 2009

Если вы говорите на MS SQL, вот самый эффективный способ. Это извлекает текущее начальное значение идентификатора из таблицы на основе того, какой столбец является идентификатором.

select IDENT_CURRENT('TableName') as LastIdentity

Использование MAX(id) является более общим, но, например, у меня есть таблица с 400 миллионами строк, которая занимает 2 минуты, чтобы получить MAX(id). IDENT_CURRENT почти мгновенно ...

6 голосов
/ 10 октября 2009
select max(id) from Customers 
4 голосов
/ 10 октября 2009

Если вы используете 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), и вы потеряете идентификатор первой вставки. Приведенные выше функции основаны на сеансах, поэтому, если вставляется другой сеанс, вы все равно получаете вставленный идентификатор.

2 голосов
/ 24 января 2013

Вы также можете использовать реляционную алгебру. Немного длинная процедура, но здесь просто понять, как работает MAX ():

E: = π ID (имя_таблицы)
E1: = π ID ID> = ID ' ((( ID' E) ⋈ E)) - π ID ID ((ρ ID' E) ⋈ E))

Ваш ответ: Table_Name ⋈ E1

По сути, вы вычитаете множество упорядоченных отношений (a, b), в которых a < b из A, где a, b ∈ A.

Символы алгебры отношений см .: реляционная алгебра Из Википедии

2 голосов
/ 10 октября 2009

Если вы не используете автоинкрементные поля, вы можете получить аналогичный результат с чем-то вроде следующего:

insert into Customers (ID, FirstName, LastName)
    select max(ID)+1, 'Barack', 'Obama' from Customers;

Это обеспечит отсутствие вероятности возникновения состояния гонки, которое может быть вызвано тем, что кто-то еще вставит в таблицу между вашим извлечением максимального идентификатора и вставкой новой записи.

Это использует стандартный SQL, без сомнения, есть лучшие способы добиться этого с помощью конкретных СУБД, но они не обязательно переносимы (к этому мы очень серьезно относимся в нашем магазине).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...