Выберите КОЛИЧЕСТВО (*) подзапроса, не выполняя его дважды

Вот простое решение поместить этот CSS

<style>
@media print{
   .noprint{
       display:none;
   }
}

и вот HTML

<div class="noprint">
    element that need to be hide when printing
</div>
<div class="noprint">
    element that need to be hide when printing
</div>
19
задан 24 February 2009 в 11:34
поделиться

5 ответов

Можно считать строки итогов как отдельный столбец в основном запросе с помощью КОЛИЧЕСТВА (*). Как это:

WITH SelectedItems AS
(SELECT Id, Row1, Row2, ROW_NUMBER() OVER (ORDER BY Row1) AS Position, 
COUNT(*) OVER () AS TotalRows
FROM Items
WHERE Row2 = @Row2)
SELECT Id, Row1, Row2
FROM SelectedItems
WHERE Position BETWEEN @From AND @To

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

DECLARE @tmp TABLE (Id int, RowNum int, TotalRows int);

WITH SelectedItems AS
(SELECT Id, Row1, Row2, ROW_NUMBER() OVER (ORDER BY Row1) AS Position, 
COUNT(*) OVER () AS TotalRows
FROM Items
WHERE Row2 = @Row2)
INSERT @tmp
SELECT Id, Row1, Row2
FROM SelectedItems
WHERE Position BETWEEN @From AND @To

SELECT TOP 1 @TotalRows = TotalRows FROM @tmp
SELECT * FROM @tmp

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

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

19
ответ дан 30 November 2019 в 04:21
поделиться

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

Теоретически, SQL Server даже не мог бы пройти все строки в подзапросе, чтобы смочь считать его.

3
ответ дан 30 November 2019 в 04:21
поделиться

У меня нет доступа к моей кодовой базе прямо сейчас, но я полагаю, что можно использовать КОЛИЧЕСТВО () ПО (или подобная команда) для возврата общего количества строк как часть подзапроса. Можно тогда возвратить это как часть набора конечного результата. Это дублировано в каждой строке, но это - незначительный хит производительности, по-моему, для приложения, которое использует подкачку страниц и должно было ограничить конечные результаты так или иначе.

Через пару часов я отправлю точный код.

РЕДАКТИРОВАНИЕ: вот строка, что я раньше генерировал количество. В конце наши разработчики хотели отдельный метод получить количество отдельно, поэтому теперь я поддерживаю критерии поиска в двух местах в рамках той же хранимой процедуры.

COUNT(*) OVER (PARTITION BY '') AS TotalCount

Добавляют, что к Вашему CTE и затем можно выбрать TotalCount, и это будет столбец в каждой из строк.

2
ответ дан 30 November 2019 в 04:21
поделиться

Вы не могли только установить выходную переменную на @@ RowCount? Это будет влиять на строки последним выполняемым оператором:

SELECT stuff FROM mytable

SET @output = @@ROWCOUNT

Это должно дать Вам, в чем Вы нуждаетесь, и не включает выполнение запроса снова.

1
ответ дан 30 November 2019 в 04:21
поделиться

Вы ДОЛЖНЫ выполнить весь запрос без ограничения диапазона хотя бы один раз, чтобы получить полное количество строк. Поскольку вы все равно собираетесь это сделать, вам следует выбрать @@ RowCount, чтобы вывести все найденные строки, а не перегружать средство чтения данных избыточным столбцом count (*) в каждой строке.

1. При первом запуске запроса NEW:

select YOUR_COLUMNS 
from YOUR_TABLE 
where YOUR_SEARCH_CONDITION 
order by YOUR_COLUMN_ORDERING_LIST;
select @@rowcount;

2. ЧИТАЙТЕ только первые X строк

Вышеупомянутый запрос позволяет избежать переполнения вашего SqlDataReader избыточного столбца COUNT (*), который в противном случае отправлялся бы при каждом вызове SqlDataReader.Read (). Поскольку вы запускаете запрос впервые ... вместо выбора диапазона просто ПРОЧИТАЙТЕ только первые X строк. Это дает вам именно то, что вы хотите ... полный счетчик результатов, первые X записей и эффективную потоковую передачу набора результатов без избыточного столбца счетчика.

3. Для последующих запусков ОДНОГО запроса для получения подмножества результатов

select YOUR_COLUMNS 
from (select YOUR_COLUMNS, ROW_NUMBER() 
over(order by BY YOUR_COLUMN_ORDERING_LIST) as RowNum) Results 
where Results.RowNum between @From and @To;

В любом случае, @@ rowcount является наиболее прямым способом доступа к счетчику при первом запуске запроса без ограничения результата. set (вы все равно захотите получить первые результаты X), без запуска отдельного запроса count (), без использования временной таблицы и без включения избыточного столбца count ().

2
ответ дан 30 November 2019 в 04:21
поделиться
Другие вопросы по тегам:

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