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

Ваш сервер получит запрос и ответ. Из запроса вы можете получить URL, проанализировать его, а затем получить объект запроса.

server = function(req, res) {
  // Get the URL and parse it
  const parsedUrl = url.parse(req.url, true);

  // Get the query string as an object
  const queryStringObject = parsedUrl.query;

  if (queryStringObject.id) {
    // Do stuff
  }
};
32
задан antik 28 October 2008 в 16:37
поделиться

9 ответов

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

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

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

16
ответ дан 27 November 2019 в 20:45
поделиться

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

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

SELECT @@Rowcount

Или если Вы хотите расположить в ряд количество, включенное в результат, отправленный подобным для Приближения к № 2, можно использовать ПО пункту .

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

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

RowCount в ответ на комментарий: пример, который я дал, даст # строк в разделе - определенный в этом случае "РАЗДЕЛОМ my_table.foo". Значение столбца в каждой строке является # строк с тем же значением my_table.foo. Так как Ваш запрос в качестве примера имел пункт, "ГДЕ my_table.foo = 'панель'", все строки в наборе результатов будут иметь то же значение my_table.foo и поэтому значение в столбце, будет тем же для всех строк и равный (в этом случае) это # строк в запросе.

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

SELECT my_table.my_col, count(*) OVER() AS 'Count'
  FROM my_table
 WHERE my_table.foo = 'bar'
29
ответ дан 27 November 2019 в 20:45
поделиться

Подход 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';
3
ответ дан 27 November 2019 в 20:45
поделиться

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

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, чтобы получить количество строк, затронутых последним оператором и перенаправить вывод реальный запрос к временной таблице или табличной переменной, таким образом, можно возвратить все в целом и никакую потребность транзакции:

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
ответ дан 27 November 2019 в 20:45
поделиться

Вот некоторые идеи:

  • Идут с Подходом № 1 и изменяют размер массива, чтобы содержать дополнительные результаты или использовать тип, который автоматически изменяет размер как необходимый (Вы не упоминаете, какой язык Вы используете так, я не могу быть более конкретным).
  • Вы могли выполнить оба оператора в Подходе № 1 в рамках транзакции, чтобы гарантировать, что количества те же оба раза если Ваша поддержка БД это.
  • я не уверен, что Вы делаете с данными, но если возможно обработать результаты, не храня всех их сначала, что это могло бы быть лучшим методом.
1
ответ дан 27 November 2019 в 20:45
поделиться

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

1
ответ дан 27 November 2019 в 20:45
поделиться

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

0
ответ дан 27 November 2019 в 20:45
поделиться

Вы могли бы хотеть думать о лучшем шаблоне для контакта с данными этого типа.

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

количество строк не изменится - Google для ACID и SQL.

0
ответ дан 27 November 2019 в 20:45
поделиться
IF (@@ROWCOUNT > 0)
BEGIN
SELECT my_table.my_col
  FROM my_table
 WHERE my_table.foo = 'bar'
END
0
ответ дан 27 November 2019 в 20:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: