Нужно количество строк после инструкции SELECT: какой оптимальный подход SQL? Количество строк sql


Функция COUNT - подсчет количества записей

Функция COUNT подсчитывает количество записей в таблице.

Условие, по которому будут выбираться записи, задается с помощью команды WHERE.

Команда WHERE не является обязательной, если ее не указать - будут подсчитаны все записи в таблице.

См. также команду DISTINCT, которая позволяет подсчитывать только уникальные значения поля.

См. также команду GROUP BY, которая позволяет группировать записи и затем с помощью COUNT подсчитывать количество в группах.

Синтаксис

Подсчет всех записей:

SELECT COUNT(*) FROM имя_таблицы WHERE условие

Подсчет всех записей, где заданное поле не равно NULL:

SELECT COUNT(поле) FROM имя_таблицы WHERE условие

Только уникальные значения поля:

SELECT COUNT(DISTINCT поле) FROM имя_таблицы WHERE условие

Примеры

Все примеры будут по этой таблице workers, если не сказано иное:

id айди name имя age возраст salary зарплата
1 Дима 23 400
2 Петя 25 500
3 Вася 23 500
4 Коля 30 1000
5 Иван 27 500
6 Кирилл 28 1000

Пример

Давайте подсчитаем всех работников с возрастом 23 года:

SELECT COUNT(*) as count FROM workers WHERE age=23

Результат выполнения SQL запроса:

count результат подсчета
2

Пример

Давайте подсчитаем количество разных зарплат (их будет 3 штуки: 400, 500 и 1000):

SELECT COUNT(DISTINCT salary) as count FROM workers

Результат выполнения SQL запроса:

count результат подсчета
3

Пример

Давайте подсчитаем одновременно количество разных возрастов и количество разных зарплат:

SELECT COUNT(DISTINCT age) as count1, COUNT(DISTINCT salary) as count2 FROM workers

Результат выполнения SQL запроса:

count1 количество возрастов count2 количество зарплат
5 3

Меняем таблицу для примеров

Все примеры ниже будут по этой таблице workers, если не сказано иное:

id айди name имя age возраст salary зарплата
1 Дима 23 NULL
2 Петя 25 500
3 Вася 23 NULL

Пример

Давайте подсчитаем количество всех записей:

SELECT COUNT(*) as count FROM workers

Результат выполнения SQL запроса:

count результат подсчета
3

А теперь подсчитаем количество зарплат, не равных NULL:

SELECT COUNT(salary) as count FROM workers

Результат выполнения SQL запроса:

count результат подсчета
1

code.mu

какой оптимальный подход SQL? Безопасный SQL

Я пытаюсь выбрать столбец из одной таблицы (нет объединений), и мне нужно подсчитать количество строк, в идеале, прежде чем я начну извлекать строки. Я пришел к двум подходам, которые предоставляют необходимую мне информацию.

Я делаю это, потому что мой SQL-драйвер (SQL Native Client 9.0) не позволяет мне использовать SQLRowCount в инструкции SELECT, но мне нужно знать количество строк в моем результате, чтобы выделить массив перед назначением ему информации. Использование динамически выделенного контейнера, к сожалению, не является вариантом в этой области моей программы.

Я обеспокоен тем, что может произойти следующий сценарий:

Кроме того, будет ли один из двух подходов быстрее? Если да, то какой?

Наконец, есть ли лучший подход, который я должен рассмотреть (возможно, способ дать указание драйверу вернуть количество строк в результате SELECT с помощью SQLRowCount?)

Для тех, кто просил, я использую Native C ++ с вышеупомянутым драйвером SQL (предоставляется Microsoft).

Есть только два способа быть на 100% уверенными, что COUNT(*) и фактический запрос дадут согласованные результаты:

  • Объедините COUNT(*) с запросом, как и в вашем подходе 2. Я рекомендую форму, которую вы показываете в своем примере, а не коррелированную форму подзапроса, указанную в комментарии от kogus.
  • Используйте два запроса, как в вашем подходе 1, после запуска транзакции на SERIALIZABLE изоляции SNAPSHOT или SERIALIZABLE .

Использование одного из этих уровней изоляции важно, потому что любой другой уровень изоляции позволяет новым строкам, созданным другими клиентами, стать видимыми в текущей транзакции. Для получения дополнительной информации прочитайте документацию MSDN для SET TRANSACTION ISOLATION .

Если вы используете SQL Server, после запроса вы можете выбрать функцию @@ RowCount (или если ваш результирующий набор может иметь более 2 миллиардов строк, используйте функцию BIGROW_COUNT ()). Это вернет количество строк, выбранных предыдущим оператором, или количество строк, на которые влияет инструкция insert / update / delete.

SELECT my_table.my_col FROM my_table WHERE my_table.foo = 'bar' SELECT @@Rowcount

Или, если вы хотите подсчитать количество, включенное в результат, отправленный аналогично подходу №2, вы можете использовать предложение OVER (см. http://msdn.microsoft.com/en-us/library/ms189461.aspx 1 ).

SELECT my_table.my_col, count(*) OVER(PARTITION BY my_table.foo) AS 'Count' FROM my_table WHERE my_table.foo = 'bar'

Использование предложения OVER будет иметь гораздо лучшую производительность, чем использование подзапроса, чтобы получить количество строк. Использование @ @ RowCount будет иметь лучшую производительность, потому что не будет никакой стоимости запроса для оператора select @@ RowCount

Обновление в ответ на комментарий: в примере, который я дал, будет указано количество строк в разделе, определяемое в этом случае «PARTITION BY my_table.foo». Значение столбца в каждой строке – это число строк с таким же значением my_table.foo. Поскольку ваш примерный запрос имел предложение WHERE my_table.foo = 'bar' ", все строки в наборе результатов будут иметь то же значение my_table.foo, и поэтому значение в столбце будет одинаковым для всех строк и равно (в этот случай) это # ​​строк в запросе.

Вот лучший / более простой пример того, как включить столбец в каждую строку, которая является полным количеством строк в наборе результатов. Просто удалите необязательное предложение Partition By.

SELECT my_table.my_col, count(*) OVER() AS 'Count' FROM my_table WHERE my_table.foo = 'bar'

Подход 2 всегда будет возвращать счетчик, соответствующий вашему результирующему набору.

Я предлагаю вам связать суб-запрос с внешним запросом, чтобы гарантировать, что условие в вашем счете соответствует условию в наборе данных.

SELECT mt.my_row, (SELECT COUNT(mt2.my_row) FROM my_table mt2 WHERE mt2.foo = mt.foo) as cnt FROM my_table mt WHERE mt.foo = 'bar';

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

BEGIN TRAN bogus SELECT COUNT( my_table.my_col ) AS row_count FROM my_table WHERE my_table.foo = 'bar' SELECT my_table.my_col FROM my_table WHERE my_table.foo = 'bar' ROLLBACK TRAN bogus

Это всегда вернет правильные значения.

Кроме того, если вы используете SQL Server, вы можете использовать @@ ROWCOUNT для получения количества строк, затронутых последним оператором, и перенаправить вывод реального запроса в таблицу temp или таблицу, чтобы вы могли полностью вернуть все, и нет необходимости в транзакции:

DECLARE @dummy INT SELECT my_table.my_col INTO #temp_table FROM my_table WHERE my_table.foo = 'bar' SET @dummy=@@ROWCOUNT SELECT @dummy, * FROM #temp_table

Вот несколько идей:

  • Перейдите с подходом №1 и измените размер массива на наличие дополнительных результатов или используйте тип, который автоматически изменяет размер по мере необходимости (вы не укажете, какой язык вы используете, поэтому я не могу быть более конкретным).
  • Вы можете выполнять оба оператора в подходе №1 в транзакции, чтобы гарантировать, что подсчеты совпадают оба раза, если ваша база данных поддерживает это.
  • Я не уверен, что вы делаете с данными, но если можно обрабатывать результаты, не сохраняя их все сначала, это может быть лучшим методом.

Если вы действительно обеспокоены тем, что количество строк будет меняться между подсчетом выбора и оператором select, почему бы не сначала выбрать ваши строки в таблице temp? Таким образом, вы знаете, что будете синхронизированы.

Почему бы вам не поместить свои результаты в вектор? Таким образом, вам не нужно знать размер перед рукой.

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

Никакой самонаблюдательный драйвер SQL не скажет вам, сколько строк ваш запрос вернется, прежде чем возвращать строки, потому что ответ может измениться (если вы не используете транзакцию, которая создает проблемы самостоятельно).

Количество строк не изменится – google для ACID и SQL.

IF (@@ROWCOUNT > 0) BEGIN SELECT my_table.my_col FROM my_table WHERE my_table.foo = 'bar' END

Просто добавьте это, потому что это лучший результат в google для этого вопроса. В sqlite я использовал это, чтобы получить rowcount.

WITH temptable AS (SELECT one,two FROM (SELECT one, two FROM table3 WHERE dimension=0 UNION ALL SELECT one, two FROM table2 WHERE dimension=0 UNION ALL SELECT one, two FROM table1 WHERE dimension=0) ORDER BY date DESC) SELECT * FROM temptable LEFT JOIN (SELECT count(*)/7 AS cnt, 0 AS bonus FROM temptable) counter WHERE 0 = counter.bonus

sql.fliplinux.com

sql - Нужно количество строк после инструкции SELECT: какой оптимальный подход SQL?

Если вы используете SQL Server, после вашего запроса вы можете выбрать функцию @@RowCount (или если в вашем результирующем наборе может быть более 2 миллиардов строк, используйте функцию BIGROW_COUNT()). Это вернет количество строк, выбранных предыдущим оператором, или количество строк, на которые влияет инструкция insert/update/delete.

SELECT my_table.my_col FROM my_table WHERE my_table.foo = 'bar' SELECT @@Rowcount

Или, если вы хотите подсчитать счет, включенный в результат, отправленный аналогично подходу №2, вы можете использовать предложение OVER (см. http://msdn.microsoft.com/en-us/library/ms189461.aspx 1).

SELECT my_table.my_col, count(*) OVER(PARTITION BY my_table.foo) AS 'Count' FROM my_table WHERE my_table.foo = 'bar'

Использование предложения OVER будет иметь гораздо лучшую производительность, чем использование подзапроса, чтобы получить количество строк. Использование @@RowCount будет иметь лучшую производительность, потому что не будет никакой стоимости запроса для выражения select @@RowCount

Обновление в ответ на комментарий: в примере, который я дал, будет указано количество строк в разделе, определяемое в этом случае "PARTITION BY my_table.foo". Значение столбца в каждой строке - это число строк с таким же значением my_table.foo. Поскольку ваш примерный запрос имел предложение WHERE my_table.foo = 'bar' ", все строки в наборе результатов будут иметь то же значение my_table.foo, и поэтому значение в столбце будет одинаковым для всех строк и равно (в этот случай) это # ​​строк в запросе.

Вот лучший/более простой пример того, как включать столбец в каждую строку, которая является полным количеством строк в наборе результатов. Просто удалите необязательное предложение Partition By.

SELECT my_table.my_col, count(*) OVER() AS 'Count' FROM my_table WHERE my_table.foo = 'bar'

qaru.site

[count] Количество строк в таблице SQL в O (1) [performance]

В некоторых RDBM это O (1) (в первую очередь MySQL), ставьте AFAIK, как правило, он нахмурился и считается «уродливым взломом производительности». Причиной является то, что если у вас есть транзакции (которые должны иметь все реальные RDBM), общее количество строк в таблице может быть или не быть равно общему числу, которое вы можете видеть из текущей транзакции . Вот почему серверу необходимо проверить, какие строки на самом деле видимы для вашей транзакции, делая его более O (n), чем O (1).

Если вы хотите оптимизировать процесс получения количества строк и удовлетворены приблизительным результатом, у большинства RDBM есть специальные «информационные» таблицы, которые содержат информацию о таблицах, включая приблизительное количество строк (опять же, это не точный количество строк из-за транзакций).

Производительность COUNT (*) на основе индекса или таблицы действительно зависит от размера сегмента. У вас может быть таблица 1GB, в которой есть только одна строка, но Oracle все равно придется сканировать все выделенное пространство. Вставка еще одного миллиона строк может вообще не повлиять на производительность, если она не изменит знак высокой воды. Индексы работают аналогичным образом, когда различные шаблоны удалений могут оставлять разное количество свободного места в структуре индекса и вызывать сканирование индекса, чтобы обеспечить лучшую или худшую производительность, чем O (N).

Итак, теоретически это O (N). На практике возникают проблемы с усыплением, которые могут сильно отличаться.

Например, есть случаи, когда хранилище данных Oracle может дать лучшую производительность O (N). В частности, оптимизатор может сканировать индекс растрового изображения, а размер индекса растрового изображения слабо связан с размером таблицы, в отличие от индекса b-дерева. Это связано с методологией сжатия, которая делает размер индекса зависящим от размера таблицы, количеством уникальных значений, распределением значений по всей таблице и историческим шаблоном загрузки, как я полагаю. Таким образом, удвоение количества строк в таблице может только увеличить размер индекса на 10%.

При наличии материализованного представления вы также можете получить O (1), прочитав сводную таблицу (триггер - небезопасный способ сделать это).

Это не постоянное время, потому что в транзакционных механизмах необходимо проверить, сколько строк существует в текущей транзакции, что обычно включает в себя сканирование всей таблицы.

Оптимизация COUNT (*) без предложения where не является особенно полезной оптимизацией для работы базы данных за счет других вещей; пользователи больших таблиц редко делают такой запрос, и это вообще не помогло бы, если бы существовало предложение WHERE.

MyISAM в MySQL «обманывает», сохраняя точное количество строк, но он может это сделать только потому, что у него нет MVCC, поэтому не нужно беспокоиться о том, в каких транзакциях находятся строки.

Обычно это O (N).

Если требуется O (1) ответ на такой запрос, вы можете легко выполнить его либо с помощью:

  • Индексированное представление, которое подсчитывает запрос.
  • Храните счет вручную в другой таблице и обновляйте счетчик строк с помощью триггера:

Пример:

CREATE TABLE CountingTable ( Count int ) INSERT CountingTable VALUES(0) CREATE TRIGGER Counter ON Table FOR INSERT, UPDATE, DELETE AS BEGIN DECLARE

code-examples.net

sql-server - Максимальное количество строк в таблицах SQL Server

Как правило, мы можем дать больше максимальных значений, сколько строк может иметь таблица в SQL Server? После этого мы не можем добавить новую строку.

источник поделиться

Есть несколько случаев краев (за пределами очевидной проблемы с дисковым пространством), где SQL Server не позволит вам добавлять больше строк, а не о количестве строк точно, но стоит упомянуть:

  • у вас есть столбец IDENTITY, и вы попадаете в конец диапазона для типа данных, например. 255 для TINYINT, 2 147 483 647 для INT, какое-то нечестивое число, которое начинается с 9 - возможно, число дюймов на солнце и обратно - для BIGINT и т.д. Когда вы пытаетесь вставить следующую строку, Появится сообщение об ошибке 815 о переполнении типа. Это не имеет никакого отношения к количеству строк, уже находящихся в таблице, по сути, а скорее к количеству строк, которые вы уже пытались вставить (без повторного посева столбца IDENTITY). Если у вас высокий процент откатов (или большое количество успешных вставок), вы можете отслеживать максимальное значение в этом столбце с течением времени.

  • Если у вас есть куча с уникальным индексом или кластеризованный индекс, который не является уникальным, вы не сможете хранить более 2 * 2,147,483,647 уникальных комбинаций клавиш индекса. Когда вы пытаетесь вставить (2 * 2,147,483,647) + 1 строку со значением 1 в столбце INT, который является единственным столбцом в кластерном индексе, вы получите сообщение об ошибке 666 об исчерпании идентификатора. Это связано с тем, что уникальный идентификатор (который помогает SQL Server идентифицировать строку, когда нет истинного ключа) составляет всего 4 байта, что означает, что он не может превышать емкость INT (он использует как положительные, так и отрицательные, в отличие от IDENTITY, если не настроить его как таковое, поэтому вы получаете двойной). Теперь, почему вы это сделаете, <shrug> ... но вы могли бы.

  • в пространстве VLDB, база данных может быть только 524 272 терабайт. Опять же очень кромка, но если у вас есть обширный хранилище данных, то, очевидно, в какой-то момент количество строк - в зависимости от размера строки - приблизит вас к этому пределу. Я думаю, что базы данных петабайтов, в то время как они якобы существуют в каком-то уголке какой-либо лаборатории где-то, в основном теоретические. Я полагаю, что технически выражение "Ограниченное доступное хранилище" на странице Max Capacity для SQL Server могло учитывать этот максимальный размер, или они могли просто предположить, что никто никогда не будет имеют более 524 272 терабайт памяти, доступных одному экземпляру SQL Server (вероятно, это разумное предположение сегодня, но так было 640 Кбайт ОЗУ, один раз: -)).

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

источник поделиться

Количество строк в SQL Server ограничено только хранилищем, доступным самой базе данных. Если вы не нажмете этот предел, я сомневаюсь, что вы когда-нибудь столкнетесь с ситуацией, когда вы не можете добавить строки в таблицу.

В чем проблема, точно? Это поможет. Сообщения об ошибках?

ответ дан kprobst 25 авг. '11 в 8:31 источник поделиться

Я не знаю числа строк и не уверен, есть ли такое число. Но я знаю таблицы с более чем 100 миллионами строк.

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

ответ дан CharithJ 25 авг. '11 в 8:33 источник поделиться

qaru.site

Подсчёт количества строк в таблице MySQL

Всем нам наверняка приходилось подсчитать количество строк в той или иной таблице,или выборке. Сделать это можно различными способами. В той или иной ситуации можно использовать любой из этих способов. Рассмотрим самый простой способ. Просто сделаем выборку и при переборе всех строк накрутим счётчик, который и будет содержать количество строк.
  1. $i=0;

  2. $sql='select * from `table`';

  3. $i++;

  4. }

  5. echo 'В таблице '.$i.' строк';

Недостаток данного метода-это извлечение значений всех столбцов таблицы(когда нам это не надо). Использовать такой подход можно в том случае, когда при обходе таблицы базы данных вы совершаете другие операции. Например нам надо извлечь имена пользователей и сложить их в массив:
  1. $i=0;

  2. $sql='select name from `users`';

  3. $users_name[]=$row['name'];

  4. $i++;

  5. }

  6. echo 'В таблице '.$i.' пользователей';

Таким образом мы убили двух зайцев: сформировали массив и подсчитали количество строк. Также обратите внимание на то, что из таблицы мы извлекали только поле name, а не *. Старайтесь всегда извлекать только нужные вам поля,т.к. при больших объёмах данных это будет играть существенную роль. В конкретном случае можно подсчитать и количество элементом массива $users_name[] функцией count.
  1. $count_users = count($users_name);
Второй метод. Использование функции mysql_num_rows. Посчитаем количество животных в таблице pets.
  1. $sql='select * from `pets`';

  2. echo 'В таблице '.$count_pets.' животных';

Третий способ. Найдем количество автомобилей в таблице cars.
  1. $sql='select count(*) as count_cars from `cars`';

  2. $count_cars=$counts['count_cars'];

  3. echo 'В таблице '.$count_cars.' автомобилей';

И четвёртый способ.Подсчитаем количество голосов в таблице.
  1. $sql='select SQL_CALC_FOUND_ROWS * from `golosa`';

php-include.ru

Урок 8. Группировка записей и функция COUNT()

 Давайте вспомним, какие сообщения и в каких темах у нас имеются. Для этого можно воспользоваться привычным запросом:

А что, если нам надо лишь узнать сколько сообщений на форуме имеется. Для этого можно воспользоваться встроенной функцией COUNT(). Эта функция подсчитывает число строк. Причем, если в качестве аргумента этой функции выступает *, то подсчитываются все строки таблицы. А если в качестве аргумента указывается имя столбца, то подсчитываются только те строки, которые имеют значение в указанном столбце.

В нашем примере оба аргумента дадут одинаковый результат, т.к. все столбцы таблицы имеют тип NOT NULL. Давайте напишем запрос, используя в качестве аргумента столбец id_topic:

SELECT COUNT(id_topic) FROM posts;

Итак, в наших темах имеется 4 сообщения. Но что, если мы хотим узнать сколько сообщений имеется в каждой теме. Для этого нам понадобится сгруппировать наши сообщения по темам и вычислить для каждой группы количество сообщений. Для группировки в SQL используется оператор GROUP BY. Наш запрос теперь будет выглядеть так:

SELECT id_topic, COUNT(id_topic) FROM posts GROUP BY id_topic;

Оператор GROUP BY указывает СУБД сгруппировать данные по столбцу id_topic (т.е. каждая тема - отдельная группа) и для каждой группы подсчитать количество строк:

Ну вот, в теме с id=1 у нас 3 сообщения, а с id=4 - одно. Кстати, если бы в поле id_topic были возможны отсутствия значений, то такие строки были бы объединены в отдельную группу со значением NULL.

Предположим, что нас интересуют только те группы, в которых больше двух сообщений. В обычном запросе мы указали бы условие с помощью оператора WHERE, но этот оператор умеет работать только со строками, а для групп те же функции выполняет оператор HAVING:

SELECT id_topic, COUNT(id_topic) FROM posts GROUP BY id_topic HAVING COUNT(id_topic) > 2;

В результате имеем:

В уроке 4 мы рассматривали, какие условия можно задавать оператором WHERE, те же условия можно задавать и оператором HAVING, только надо запомнить, что WHERE фильтрует строки, а HAVING - группы.

Итак, сегодня мы узнали, как создавать группы и как подсчитать количество строк в таблице и в группах. Вообще вместе с оператором GROUP BY можно использовать и другие встроенные функции, но их мы будем изучать позже.

Предыдущий урок Вернуться в раздел Следующий урок 

www.site-do.ru