2009-10-10 3 views
34

Допустим, у меня есть следующие данные в таблице Customers: (ничего больше)SQL - Как найти наибольшее число в столбце?

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

Какой ЗЕЬЕСТ может получить мне номер 22, в столбце ID?

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

Я подумал о «SELECT ID FROM Клиенты» и подсчет строк вернулся, но это кажется ужасно ineffecient и в этом случае, это будет неправильно возвращать «3», хотя мне нужен уникальный идентификатор 23.

+3

Никакого неуважения к msaeed, но Brisbe42 & D Ответы Андреса лучше. –

+0

Отличный момент, но их ответы прямо не отвечают на мой вопрос. Мой метод безопасен, так как я получаю бесплатный идентификатор, а затем добавляю запись. Конечно, вы могли бы сказать, что одновременные операции могут испортить это несколькими программами, получая один и тот же «свободный» ID и повторно используя его ... но этого можно избежать, добавив запись супер быстро после получения бесплатного идентификатора. –

+0

msaeed и некоторые другие отвечают на ваш вопрос * точно *. Вопрос: «SQL - как найти наибольшее число в столбце?» и «Какой оператор SELECT может получить мне номер 22 в столбце ID?».Исправьте свой пост, чтобы уточнить ваши намерения. – Liao

ответ

8

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

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

16

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

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

SET @mostRecentId = SCOPE_IDENTITY() 

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

3

При использовании использование AUTOINCREMENT:

ВЫБОР LAST_INSERT_ID();

Assumming, что вы используете Mysql: http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html

Postgres обрабатывает это аналогично с помощью функции CURRVAL (sequence_name).

Обратите внимание, что использование MAX (ID) небезопасно, если вы не заблокируете таблицу, так как это возможно (в упрощенном случае) иметь другую вставку, которая возникает до вызова MAX (ID), и вы теряете идентификатор первая вставка. Функции, описанные выше, основаны на сеансе, поэтому, если в другой сеанс встает, вы все равно получаете введенный идентификатор.

+0

Использование вставки с подзапросом делает сейф max (id) безопасным, см. Мой ответ. Но, честно говоря, автоинкремент - лучший выбор, если он доступен, и вы тоже не слишком обеспокоены переносимостью. – paxdiablo

+0

+1 за то, что MAX (ID) небезопасен –

0

В зависимости от того, какую версию SQL вы используете. Как MySQL, так и SQLite, например, имеют способы получить последний идентификатор вставки. На самом деле, если вы используете PHP, есть даже отличная функция для этого mysql_insert_id().

Возможно, вы должны использовать эту функцию MySQL вместо того, чтобы смотреть на все строки, чтобы получить самый большой идентификатор вставки. Если ваш стол станет большим, это может стать очень неэффективным.

2

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

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

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

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

7

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

select IDENT_CURRENT('TableName') as LastIdentity 

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

+1

Мне нужно будет зафиксировать это в памяти. Хорошая вещь. –

+1

Действительно? Пара минут? У вас есть индекс на id? Он должен быть почти мгновенным, чтобы найти мин или максимум, даже с 400 миллионами строк. – paxdiablo

+0

Это неспецифический, некластеризованный индекс «идентификатора» ... не уверен, что это правильный дизайн для приложения, но это то, что он есть. SQL 2005 Enterprise со схемой partion – Damon

-1
select * from tablename order by ID DESC 

, который даст вам грести с идентификатором 22

+0

Это вернет все строки; с правильным в верхней части результирующего набора. Он не будет возвращать только строку с максимальным id. – Ben

6
SELECT * FROM Customers ORDER BY ID DESC LIMIT 1 

Затем получить идентификатор.

2

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

E: = π ID (table_name)
E1: = π ID ID> = ID» ((ρ ID ' E) ⋈ E)) - π ID ID < ID' ((ρ ID» E) ⋈ E))

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

В основном то, что вы делаете, это вычитать множество упорядоченных соотношений (а, б), в котором < Ь из А, где а, Ь ∈ A.

Для соотношения алгебры символов см: Relational algebra From Wikipedia

+7

Я не думаю, что решения реляционной алгебры будут хорошо приняты для вопросов SQL. –

0

В 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.

+0

Это вопрос о SQL. –