Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
использую paging
declare @count int

WITH Members  AS
(  select * ,
   ROW_NUMBER() OVER (order by [date] desc) AS RowNumber,	
   COUNT(*) OVER (PARTITION BY NULL) AS [rowcount]
   from table  x 
 )
select * from Members  
where RowNumber between 1 and 10


работает
но мне нужно
дополнительно к показу таблицы сохранить значение [rowcount] в переменной @count (output)
можно ли как то избежать использование ещё таблицы и применить тот же СТЕ ?
18 июн 12, 14:57    [12731924]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
set @count = @@rowcount
18 июн 12, 15:47    [12732472]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
нет мне нужно общее кол-во записей
18 июн 12, 15:50    [12732511]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Гавриленко Сергей Алексеевич
Member

Откуда:
Сообщений: 37254
michael R
нет мне нужно общее кол-во записей
Общее кол-во записей можно выбрать из sys.partitions. Если нужна целостность, то материализуйте во времянку.
18 июн 12, 15:55    [12732561]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
а код можно примерный
спасибо
18 июн 12, 15:56    [12732576]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
то есть всё равно нужна дополнительная таблица ?
sys.partition для существующих таблиц
18 июн 12, 16:04    [12732652]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
Может, это?
OUTPUT
18 июн 12, 16:13    [12732722]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
автор
OUTPUT

на Select это мне не помoгает
18 июн 12, 16:40    [12733052]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
Конечно, фигня, но тем не менее.

declare @count int
declare @MyTable table (name sysname, [object_id] int, [create_date] datetime, RowNumber bigint,
[rowcount] bigint);

WITH Members AS
(  select  name,  object_id, [create_date],
   ROW_NUMBER() OVER (order by [create_date] desc) AS RowNumber,	
   COUNT(*) OVER (PARTITION BY NULL) AS [rowcount]
   from sys.all_objects
 )
INSERT into @MyTable OUTPUT inserted.*
SELECT * FROM Members

SELECT TOP(1) @count = [rowcount] FROM @MyTable

SELECT @count
18 июн 12, 17:20    [12733495]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
ну вроде сделал
кажется не совсем по дурацки
правда все равно ещё таблица - размер соответствует кол-ву paging
и второй CTE для общего кол-ва
если интересно могу дать код
19 июн 12, 11:11    [12736538]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
michael R
ну вроде сделал
кажется не совсем по дурацки
правда все равно ещё таблица - размер соответствует кол-ву paging
и второй CTE для общего кол-ва
если интересно могу дать код


да, интересно. И что скажете по производительности?
Я тоже как раз хочу убрать два отдельных запроса на количество и собственно выборку и сделать одним запросом, прицепив поле к выборке...
19 июн 12, 11:45    [12736850]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
declare @count int
declare @MyTable table (name sysname, [object_id] int, [create_date] datetime, RowNumber bigint,
[rowcount] bigint ,ind int);

WITH Members AS
(  select  name,  object_id, [create_date],
   ROW_NUMBER() OVER (order by [create_date] desc) AS RowNumber,	
   COUNT(*) OVER (PARTITION BY NULL) AS [rowcount]
   from TABLE ), 
CTE2 as (
 select top 1 [rowcount]  from Members 
)
INSERT into @MyTable(name , [object_id] , [create_date] , RowNumber bigint, ind )
SELECT name , [object_id] , [create_date] , RowNumber , 1  FROM Members
where RowNumber  between 1 and 20
order by  4
UNION ALL
SELECT '' , NULL , NULL , 0, 0  
from CT2

SELECT TOP(1) @count = [rowcount] FROM @MyTable where ind=0

SELECT @count
SELECT * from @MyTable  where ind=1
19 июн 12, 11:54    [12736936]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
немно там ошибся
с сортировкой
но думаю понятно
19 июн 12, 11:56    [12736955]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
Если уж переходить на временные таблицы, то так буде проще:
declare @count int

WITH Members  AS
(  select * ,
   ROW_NUMBER() OVER (order by [create_date] desc) AS RowNumber,	
   COUNT(*) OVER (PARTITION BY NULL) AS [rowcount]
   from sys.all_objects
 )
select * INTO #Members from Members  
where RowNumber between 1 and 10

SELECT TOP(1) @count = [rowcount] FROM #Members
SELECT @count

select * FROM #Members

DROP TABLE #Members
19 июн 12, 12:10    [12737111]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
не правильно
если после paging не содержит даных ( больше нормы)
то общее кол-во ноль
19 июн 12, 12:15    [12737164]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
Jovanny
вообщем решение правильное в случае если есть проверка при запросе
на номер страницы(не выходит за границы общего кол-ва)
и без временых таблиц
19 июн 12, 12:31    [12737330]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
michael R,

В качестве альтернативы:
1. Создать служебное индексированное представление
create view dbo.vMyTableRowCount
with schemabinding
as
select
 count_big(*) as r_Count
from
 dbo.MyTable;
go
create unique clustered index IX_vMyTableRowCount__r_Count on dbo.vMyTableRowCount (r_Count);
go

2. И использовать его
declare @count int = 0;

WITH Members  AS
(  select * ,
   ROW_NUMBER() OVER (order by [date] desc) AS RowNumber
   from dbo.MyTable 
 )
select * from Members  
where RowNumber between 1 and 10;

if @@rowcount > 0
 select @count = r_Count from dbo.vMyTableRowCount;
19 июн 12, 13:26    [12737911]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
Мне кажется, не совсем корректно.
declare @count int = 0;

-- тут какая-то сессия хочет вставить или удалить строки из dbo.MyTable, но ждёт снятия блокировки 
WITH Members  AS
(  select * ,
   ROW_NUMBER() OVER (order by [date] desc) AS RowNumber
   from dbo.MyTable 
 )
select * from Members  
where RowNumber between 1 and 10;
-- блокировка снята, сессия вставляет или удаляет строки из dbo.MyTable, предварительно заблокировав строку, 
--страницу или таблицу 
if @@rowcount > 0
 select @count = r_Count from dbo.vMyTableRowCount;
-- и @count покажет что-то другое
19 июн 12, 13:38    [12738065]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
michael R
Member

Откуда: из-за границы
Сообщений: 2113
r_Count (View) не то
если стоят ещё условия на ограничение
19 июн 12, 14:03    [12738382]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
Jovanny,

Это зависит от TIL. Read committed гарантирует только отсутствие грязного чтения, так и для
WITH Members  AS
(  select * ,
   ROW_NUMBER() OVER (order by [date] desc) AS RowNumber,	
   COUNT(*) OVER (PARTITION BY NULL) AS [rowcount]
   from table  x 
 )
select * from Members  
where RowNumber between 1 and 10
нет гарантий, что [rowcount] будет содержать количество строк в таблице на момент начала инструкции. Вот статья на эту тему -- Timebomb - Consistency problem with READ COMMITTED
19 июн 12, 14:09    [12738463]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
michael R
r_Count (View) не то
если стоят ещё условия на ограничение
Тогда оглашайте все условия задачи сразу.
19 июн 12, 14:11    [12738503]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
invm
Это зависит от TIL.

Конечно. Это я навскидку привёл пример, что это решение в общем случае не корректно.
19 июн 12, 14:29    [12738670]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
invm
Member

Откуда: Москва
Сообщений: 9838
Jovanny,

Оно не более некорректно, чем если бы все было объединено в одну инструкцию.
19 июн 12, 15:07    [12739089]     Ответить | Цитировать Сообщить модератору
 Re: CTE многоразовое использование  [new]
Jovanny
Member

Откуда:
Сообщений: 1196
Ну в общем, да, согласен.
19 июн 12, 18:21    [12740925]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить