Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

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

Подход 1:

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'

Или подход 2

SELECT my_table.my_col, ( SELECT COUNT ( my_table.my_col )
                            FROM my_table
                           WHERE my_table.foo = 'bar' ) AS row_count
  FROM my_table
 WHERE my_table.foo = 'bar'

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

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

  • ВЫБРАТЬ для подсчета.
  • Выполняется другая инструкция: добавление или удаление строки.
  • Выполняется SELECT для данных, и внезапно массив имеет неправильный размер.
    -В худшем случае это попытается записать данные за пределами массива и выйдет из строя моя программа.

Запрещает 9X_sql ли подход 2 эту проблему?

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

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

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

45
0
6
Общее количество ответов: 6

Ответ #1

Ответ на вопрос: Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

Если вы используете SQL Server, после запроса 9X_sql-statement вы можете выбрать функцию @@RowCount (или, если ваш 9X_sql-statement набор результатов может содержать более 9X_sql-query 2 миллиардов строк, используйте функцию 9X_sql-select RowCount_Big()). Это вернет количество строк, выбранных 9X_sql-syntax предыдущим оператором, или количество строк, затронутых 9X_sql-syntax оператором вставки / обновления / удаления.

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

SELECT @@Rowcount

Или, если 9X_sqlselect вы хотите подсчитать количество строк, включенных 9X_sql-statement в результат, отправленный аналогично подходу 9X_sqlselect № 2, вы можете использовать тег OVER clause.

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

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

Обновление в 9X_select-statement ответ на комментарий: В приведенном мной 9X_sql примере будет указано количество строк в 9X_sql-query разделе, определяемое в данном случае как 9X_odbc «PARTITION BY my_table.foo». Значение столбца 9X_sqlselect в каждой строке - это количество строк с 9X_sql-syntax одинаковым значением my_table.foo. Поскольку 9X_sql-syntax в вашем примере запроса было предложение 9X_sqlncli «WHERE my_table.foo = 'bar'», все строки 9X_sql-statement в наборе результатов будут иметь одинаковое 9X_sqlncli значение my_table.foo, и поэтому значение 9X_sql в столбце будет одинаковым для всех строк 9X_sqlselect и равным (в в данном случае) это # ​​строк 9X_sql-query в запросе.

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

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

39
0

Ответ #2

Ответ на вопрос: Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

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

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

Использование одного из этих 9X_select-statement уровней изоляции важно, поскольку любой 9X_sqlncli другой уровень изоляции позволяет новым 9X_sql-statement строкам, созданным другими клиентами, стать 9X_sql-statement видимыми в вашей текущей транзакции. Подробнее 9X_sql-statement читайте в документации MSDN на SET TRANSACTION ISOLATION.

20
0

Ответ #3

Ответ на вопрос: Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

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

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

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';

3
0

Ответ #4

Ответ на вопрос: Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

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

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

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

Кроме того, если вы 9X_sql-syntax используете SQL Server, вы можете использовать 9X_sql-query @@ ROWCOUNT, чтобы получить количество строк, затронутых 9X_sql-statement последним оператором, и перенаправить вывод 9X_sql реального запроса во временную таблицу или таблицу. переменная, поэтому 9X_sqlncli вы можете вернуть все сразу и без транзакции:

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

3
0

Ответ #5

Ответ на вопрос: Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

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

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

9X_sql

1
0

Ответ #6

Ответ на вопрос: Требуется подсчет строк после оператора SELECT: каков оптимальный подход SQL?

Если вы действительно обеспокоены тем, что 9X_sql-query количество ваших строк изменится между счетчиком 9X_sqlncli выбора и оператором выбора, почему бы сначала 9X_odbc не выбрать свои строки во временную таблицу? Таким 9X_sqlncli образом, вы будете синхронизированы.

1
0