powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Можно ли переписать запрос без курсора?
12 сообщений из 12, страница 1 из 1
Можно ли переписать запрос без курсора?
    #38372379
Veligord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть вот такая таблица:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
CREATE TABLE [dbo].[T_Blank](
	[ID] [bigint] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,
	[UserID] [int] NULL,
	[Created] [datetime] NULL,
	[CancelDate] [datetime] NULL
 CONSTRAINT [PK_T_Blank] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 90) ON [PRIMARY]
) ON [PRIMARY]



В ней около 3 миллионов записей. В нее добавили столбец [SetId] [bigint] NULL.

Необходимо заполнить этот столбец (SetId) числами от 1 до n, где n - количество пользователей. Если есть записи с одинаковым, то для этих записей SetId - одинаковый.

Написал такой запрос:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
declare @id int
    declare @userId int
    declare @uId int = 0
	declare @setId int = 0
	
	declare  curWorkTable cursor LOCAL fast_forward read_only for
		SELECT ID, UserId from T_Blank
	open curWorkTable
	FETCH NEXT FROM curWorkTable INTO @id, @userId
	WHILE @@FETCH_STATUS = 0
	BEGIN
		if @uId != @userId
			set @setId = @setId + 1
		
		update T_Blank set SetID = @setId
			where ID = @ID
		
		set @uId = @userId
				
		FETCH NEXT FROM curWorkTable INTO @id, @userId
	END
	
	close curWorkTable



Но он на 3 миллионах записей он будет работать ну ооочень долго. Можно ли его переписать без курсора?
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38372401
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Veligord, а в каком порядке должны обрабатываться данные? в курсоре почему-то не видно ORDER BY
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38372405
Winnipuh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
немного сумбурно выглядит... или я не понял...

что вы здесь подсчитываете?

if @uId != @userId
set @setId = @setId + 1
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38372420
aleks2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VeligordМожно ли его переписать без курсора?

Ну... изучите DENSE_RANK() что ли?
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38372432
aleks2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
НО я бы сделал тупо и прямолинейно
Код: sql
1.
2.
3.
4.
5.
6.
7.
declare @t table(UserID [int] primary key clustered, i int identity);

insert @t (UserID)
  select distinct UserID from [dbo].[T_Blank];

update b set SetId = t.i
  from [dbo].[T_Blank] b inner join @t t on b.UserID = t.UserID;
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38372811
Veligord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shakil, Order by ID asc

Winnipuh,

if @uId != @userId
set @setId = @setId + 1

это проверка - если id пользователя изменилось, то SetId нужно увеличить на 1
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38372840
Ivan Durak
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
UPDATE T SET SetId = sub.cnt
FROM dbo.T_Blank T
inner join
( 
   select ID, count(UserID) as cnt FROM dbo.T_Blank group by ID 
) sub on sub.ID = T.ID 
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38373287
Veligord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ivan Durak, Спасибо, но это немного не то, что мне нужно. Этот скрипт заполняет SetId количеством вхождений пользователя в таблице. А мне нужно, чтобы было просто перечисление от 1 до n. Но, чтобы для одного пользователя SetId был одинаковый. Да, к тому же у меня этот скрипт почему-то заполняет SetId только единиицами. Хотя многие пользователи повторяются десятки и сотни раз.

Код: sql
1.
2.
3.
4.
5.
6.
UPDATE T SET SetId = sub.cnt
FROM dbo.T_Blank T
inner join
( 
   select ID, count(UserID) as cnt FROM dbo.T_Blank group by ID 
) sub on sub.ID = T.ID 
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38373314
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Veligord, а если записи с одинаковым UserId идут не подряд (order by id), то у них должен быть одинаковый setId или разный?
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38373363
Veligord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Одинаковый
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38373395
Veligord
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо, сделал вот так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
UPDATE T 
SET SetId = sub.setId
FROM dbo.T_Blank as T
inner join
( 
   select ID, Dense_RANK() OVER(ORDER BY CashierId) as setId
	from dbo.T_Blank 
) sub on sub.ID = T.ID 
...
Рейтинг: 0 / 0
Можно ли переписать запрос без курсора?
    #38373459
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VeligordВсем спасибо, сделал вот так:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
UPDATE T 
SET SetId = sub.setId
FROM dbo.T_Blank as T
inner join
( 
   select ID, Dense_RANK() OVER(ORDER BY CashierId) as setId
	from dbo.T_Blank 
) sub on sub.ID = T.ID 

Этот запрос можно написать намного короче:
Код: sql
1.
2.
WITH CTE AS(SELECT SetId,NewSetId=DENSE_RANK()OVER(ORDER BY CashierId) FROM dbo.T_Blank)
UPDATE CTE SET SetId=NewSetId;
...
Рейтинг: 0 / 0
12 сообщений из 12, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Можно ли переписать запрос без курсора?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]