Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Можно и без курсоров, наверное... / 21 сообщений из 21, страница 1 из 1
10.10.2002, 15:49:01
    #32057120
Alex_VB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Есть таблица, в таблице одно из полей - Date_check типа "smalldatetime".
Мне нужно добавить во временную таблицу #Temp1 все поля, но к значению Date_check нужно прибавлять, допустим 60 дней пока не закончится год, т.е. допустим, до 31.12.2003. Т.о. получится несколько записей относящихся к одному аппарату, но даты должны быть разные. Проще говоря, у каждого аппарата ремонт через каждые два месяца. И нужно хранить все даты его ремонта за год, т.к. впоследствие они могут корректироваться.
Можно конечно с помощью курсоров попытаться пробежаться по всем записям, но для этого надо цикл делать, можно ли одним запросом сотворить подобное?
...
Рейтинг: 0 / 0
10.10.2002, 15:53:11
    #32057122
dkstranger
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
А чем цикл не устраивает?

типа
declare @from smalldatetime
declare @to smalldatetime
declare @step int
declare @dt smalldatetime

------ .... ----
select @dt=@from
while DateDiff(day,@dt,@to)>0 begin
......
select @dt=DateAdd(day,@step,@dt)
end
...
Рейтинг: 0 / 0
10.10.2002, 15:55:54
    #32057123
jimmers
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Правильно ли я понял, что если есть исходная таблица:

id Date_check
-------------
...
1 1 Aug 2002
...

то во временной должно быть:

id Date_check
-------------
...
1 1 Aug 2002
1 1 Oct 2002
1 1 Dec 2002
...

?
...
Рейтинг: 0 / 0
10.10.2002, 16:08:04
    #32057132
Alex_VB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
to jimmers - cовершенно верно. Вы правильно поняли.
...
Рейтинг: 0 / 0
10.10.2002, 16:16:46
    #32057137
Bzzzzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
ИМХО, за один запрос без использования вспомогательной таблы(где будут опорные даты) и совсем без цикла - сомнительно....

А почему не годится

declare @i int
select @i = 1
while @i !> 12
begin
insert into #Temp1 .............
select @i = @i + 1
end

??? Или есть заморочки какиенить?
...
Рейтинг: 0 / 0
10.10.2002, 16:19:21
    #32057139
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
create table #tmp(I int)
insert #tmp(I)
select  2  uion
select  4  uion
select  6  uion
select  8  uion
select  10 

select id, DATEADD(mm, I, Date_check) as Date_check
into #MyTempTable
from MyTable, #tmp
...
Рейтинг: 0 / 0
10.10.2002, 16:27:34
    #32057150
Alex_VB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Дело в том, что 60 дней (т.е. 2 месяца) - это норматив для ремонта, это означает, что ремонт у всех аппаратов разный и прибавлять к дате нужно разное значение. Для каждого оно определено в соответствющем поле. Допустим поле Norma
...
Рейтинг: 0 / 0
10.10.2002, 16:38:50
    #32057163
Bzzzzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
DATEADD, DATEDIFF, DATEPART....
...
Рейтинг: 0 / 0
10.10.2002, 16:48:23
    #32057173
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Для ненавидящих временные таблицы:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select t.id, DATEADD(mm, I.I, t.Date_check) as Date_check
into #MyTempTable
from MyTable t
	join (select  2  as I union
		select  2  union
		select  4  union
		select  6  union
		select  8  union
		select  10 
	     ) as I on  1 = 1 
...
Рейтинг: 0 / 0
10.10.2002, 17:00:03
    #32057180
jimmers
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
IMHO в одном запросе никак не сделать - для каждой записи в исходой таблице может быть любое число записей в выходной.
...
Рейтинг: 0 / 0
10.10.2002, 17:58:18
    #32057207
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Да, если для каждого аппарата разные периоды, то так нельзя.
...
Рейтинг: 0 / 0
10.10.2002, 18:36:11
    #32057217
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
А вот и можно, через UDF
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
CREATE FUNCTION CALENDAR (
	@start_date datetime,
	@end_date datetime)
RETURNS @ret TABLE (date datetime PRIMARY KEY)
AS
BEGIN
	DECLARE @date datetime

	SET @date = @start_date
	WHILE @date <= @end_date
	BEGIN
		INSERT @ret (date)
		VALUES (@date)
		SET @date = DATEADD(d, 1 ,@date)
	END
	RETURN
END

create table #t (
  id int identity( 1 , 1 ) primary key,
  date datetime
)

insert #t
values ('01/01/01')

insert #t
values ('03/01/01')

create table #t1 (
  id int,
  date datetime
)

insert #t1
select #t.id, c.date
from #t,
	dbo.CALENDAR('01/01/01','01/01/02') c
where DATEDIFF(d,#t.date,c.date) %  60  =  0 

select * from #t1

drop table #t
drop table #t1

...
Рейтинг: 0 / 0
10.10.2002, 18:40:50
    #32057224
jimmers
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
2akuz:

Один запрос - это один запрос. Вы просто вынесли в UDF тот же цикл.
...
Рейтинг: 0 / 0
10.10.2002, 18:45:59
    #32057227
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Если я правильно понял, то я бы сделал так (ничего нового я не предлагаю, просто реализую предложенные идеи):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
set nocount on
declare @apparaty table(apparat varchar( 10 ), last datetime, period int)

insert @apparaty select 'Пылесос', '20020105', 90 
union select 'Утюг', '20020501', 30  
union select 'Вибратор', '20021031', 10  


declare @millenium table(num int)

declare @i int
set @i= 0 
while @i< 1000 
begin
  insert @millenium select @i
  set @i=@i+ 1 
end

 ------- Собственно сам запрос -------
 
select apparat,dateadd(dd, num*period, last) remont_day, num
  from @millenium m, @apparaty a
    where num< 40  and num> 0  
      and dateadd(dd, num*period, last)<'20030101'

Основное время здесь займёт заполнение таблицы @millenium числами от 0 до 999. У меня есть такая постоянная таблица, чего я и Вам желаю сделать - еще может пригодится.
...
Рейтинг: 0 / 0
10.10.2002, 19:02:17
    #32057235
akuz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
2 jimmers
Не спорю, но зато его не надо каждый раз в процедурах писать. И, помоему, на функции ещё какая-никакая оптимизация работает.
Хотя если развивать идею, то можно создать постоянную таблицу calendar заполнив её используя предлагаемый UDF.
Хотя лично у меня на рабочей станции данный UDF выдаёт сто летний диапазон за 4 сек., поэтому использовать постоянную таблицу смысла нет.
...
Рейтинг: 0 / 0
10.10.2002, 19:25:06
    #32057243
Cat2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Можно и одним запросом, только надо создать
вспомогательную таблицу.
В этой таблице должно быть поле типа Int,
содержащее последовательность от 1 до 366 и поля параметров,
которые впоследствии предполагается редактировать.

Приведенный ниже запрос создает нужную выборку,
начиная с указаной в "главной" таблице даты и
до конца года

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
set nocount on
 --Создание "главной" таблицы для тестирования
 
create table a (id int identity( 1 , 1 ), Date_check DateTime, norma int)

insert into a (Date_check, norma) values ('20020201', 10 )
 --начиная с 01.02.2002 с шагом в 10 дней
 
insert into a (Date_check, norma) values ('20020112', 20 )
 --начиная с 12.01.2002 с шагом в 20 дней
 
go

 --создание вспомогательной таблицы. 
 
 --Она создается один раз и "на века"
 
create table y (id int,param varchar( 1 ))
declare @i int
set @i= 1 

while @i<= 366 
begin
	insert into y (id) values(@i)
	set @i=@i+ 1 
end
go

 -- Выборка. Переделать ее в нужную таблицу, 
 
 -- или добавить в существующую наверняка не представляется сложным
 

select a.id,dateadd(d,y.id- 1 ,Date_check), param 
from a,y
where (y.id- 1 ) % norma= 0  
and year(dateadd(d,y.id- 1 ,Date_check))=year(Date_check)

go
drop table a
drop table y
...
Рейтинг: 0 / 0
11.10.2002, 09:15:37
    #32057320
Alex_VB
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Спасибо всем за ответы!!!
...
Рейтинг: 0 / 0
11.10.2002, 14:14:50
    #32057513
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Я не панимаю, почему все ТАК заполняют таблицы с последовательностью чисел:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
declare @i int
set @i= 0 
while @i< 1000 
begin
  insert @millenium select @i
  set @i=@i+ 1 
end


Лучьше-то без цикла:

Код: plaintext
1.
2.
3.
select top  1000  IDENTITY(int) as num
into #millenium
from syscolumns, syscolumns
...
Рейтинг: 0 / 0
11.10.2002, 14:28:33
    #32057518
jimmers
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
2alexeyvg:

1. Ваш запрос не будет работать, т.к. одной из таблиц необходимо назначитт алиас.

2. Нет гарантии, что число записей в опрашиваемых достаточно. Кстати, это же свойственно все решениям
из серии "создать впомогательную таблицу" - число
записей в ней неизвестно (в общем случае), хотя для
практичеких задач вполне можно определить.

Удачи
...
Рейтинг: 0 / 0
11.10.2002, 14:29:31
    #32057519
jimmers
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
назначит(ь)
...
Рейтинг: 0 / 0
11.10.2002, 14:36:10
    #32057527
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Можно и без курсоров, наверное...
Ну, два раза перемножить syscolumns - для данного случая хватит (в ней минимум 256 записей)
А в общем случае у меня ещё одна ошибка - поля int тоже может не хватить:-)
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Можно и без курсоров, наверное... / 21 сообщений из 21, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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