Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / можно ли сделать красиво... / 12 сообщений из 12, страница 1 из 1
14.10.2002, 10:55:43
    #32057846
Luchkin Dmitry
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Задачка:
есть таблица 1 устройств [ID] (int), [Name] (varchar), [Начало_работы] (smalldatetime);
есть таблица 2 [ID] (int), [когда] (datetime), [сколько_дней] (int)
Абсолютно точно, что "дырок", когда устройство не работает нет.
допустим самый простой вариант:
таблица1: (1, 'Агрегат#1', '2002-01-01')
таблица2: (1, '2002-01-01', 12), (1, '2002-01-02, 10)
Нужно красиво получить таблицу
(1, 12, '2002-01-01', '2002-01-13'),
(1, 10, '2002-01-13', '2002-01-23')
То есть каждая запись таблицы 2 продлевает срок использования на N дней. и нужно узнать, какая запись за какой период отвечает. Последовательность в результате должна абсолютно совпадать с последовательностью записей в таблице2.
В принципе, я сделал это, но оччень долго и некрасиво, хоть и без курсоров... Кто-нибудь знает, как это сделать просто?
...
Рейтинг: 0 / 0
14.10.2002, 12:44:19
    #32057906
Александр Степанов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Не совсем понятны условия задачи... Можно поподробнее? Желательно, с начальным набором данных пошире.
...
Рейтинг: 0 / 0
14.10.2002, 12:53:47
    #32057916
ivan999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Код: plaintext
1.
2.
3.
insert into [table3] ([ID],[number_of_days],[date_start],[date_finish])
select [ID],[сколько_дней],[когда],dateadd(day,[сколько_дней],[когда])
from [table2]

так что ли?
и что не нравится?

если скорость работы, то надо индексы расставлять
...
Рейтинг: 0 / 0
14.10.2002, 12:55:15
    #32057917
Luchkin Dmitry
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Хм... Может так понятнее будет...
Есть уйма пейджеров. Каждый из них когда-то продан, то есть есть номер и дата начала эксплуатации (таблица 1).
Обслуживание пейджера стоит денег и время от времени оплачивается по текущим на тот момент ценам (получается он оплачен тогда-то, по такой-то цене на столько-то дней /таблица 2/).
Задача узнать , в какие периоды по какой цене было обслуживание.
...
Рейтинг: 0 / 0
14.10.2002, 12:56:32
    #32057920
ivan999
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
если последовательность критична,
то order by, но это можно сделать и из финальной таблицы
...
Рейтинг: 0 / 0
14.10.2002, 14:12:15
    #32057967
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
В принципе, я сделал это, но оччень долго и некрасиво, хоть и без курсоров... Кто-нибудь знает, как это сделать просто?
Ну так Вы не стесняйтесь, напишите как Вы это реализовали. Откуда ж мы узнаем можно ли ЭТО сделать проще и красивее, если мы ЭТОГО не видели?
...
Рейтинг: 0 / 0
14.10.2002, 14:23:32
    #32057979
tygra
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Так и не понятно, что трудно сделать:
толи select написать
толи insert в таблицу №2

Чего надо то объясните

Да и какая проблема создать запись в таблице на оплату периода?
...
Рейтинг: 0 / 0
14.10.2002, 14:26:47
    #32057981
Luchkin Dmitry
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Вот какие действия необходимо предпринять:
По данному устройству из таблицы 1 берётся дата начала - запомнили @Data. Затем обрабатывается таблица 2 по порядку, в котором туда данные добавлялись: [Дата начала] = @Data, [Дата окончания] = @Data+[Дней], Затем эту расчитанную дату окончания запоминаем в @Data и так, пока данные по этому устройству. Со следующим начинаем сначала.
А как одним-двумя запросами?
...
Рейтинг: 0 / 0
14.10.2002, 14:34:23
    #32057991
Luchkin Dmitry
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Сами попросили ;-)

Код: 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.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
CREATE TABLE [#hist] (
	[Adres] [int] NULL ,
	[Data] [datetime] NULL ,
	[PlusDay] [int] NULL ,
	[Tarif] [money] NULL ,
	[Start] [smalldatetime] NULL ,
	[Final] [smalldatetime] NULL ,
	[ID] [int] IDENTITY ( 1 ,  1 ) NOT NULL
) ON [PRIMARY]

 -- Вставим во временную таблицу всю историю
 
insert #hist  --(Adres, [Data], PlusDay, Tarif, Start, Final)
 
select 	hh.Adres, 
	hh.Data,
	hh.PlusDay,
	hh.Tarif,
	cast(null as smalldatetime) as Start,
	cast(null as smalldatetime) as Final
	from history hh
where not (hh.PlusDay is Null) and (hh.PlusDay <>  0 )
order by hh.Adres, hh.Data

ALTER TABLE [#hist] WITH NOCHECK ADD 
	CONSTRAINT [IX_HIST] UNIQUE  CLUSTERED ( [Adres], [ID] ) 
	WITH  FILLFACTOR =  90   ON [PRIMARY] 

CREATE TABLE [#nav] 
	( [Adres] [int] NOT NULL, [ID] [int] NOT NULL, [Sta] [smalldatetime] ) 
	ON [PRIMARY]
ALTER TABLE [#nav] WITH NOCHECK ADD 
	CONSTRAINT [IX_NAV] UNIQUE  CLUSTERED ( [ID] ) 
	WITH  FILLFACTOR =  90   ON [PRIMARY] 

 -- Пихаем в базу начальные даты эксплуатации
 
insert #nav
select hh.Adres, MIN(hh.ID) as ID, ab.StartUse as Sta
from #hist hh
left join abonent ab ON (hh.Adres = ab.Adres)
where (hh.Start is null) and not (hh.Adres in (select distinct Adres from #hist where not Start is null))
group by hh.Adres, ab.StartUse

 -- проставляем в истории "первые" окончания сроков
 
update #hist set Start= nn.Sta, Final= cast(round(cast(nn.Sta as real) + PlusDay,  0 ,  1 ) as smalldatetime)
from #nav nn where (#hist.ID = nn.ID) and not (nn.Sta is null)

truncate table #nav
declare @Cnt bit
set @Cnt=  1 

 -- В цикле будем это делать, пока не поплохеет. 189 циклов при просчёте января 2002 :(
 
while @Cnt =  1  begin
	insert #nav
	select hh.Adres, MIN(hh.ID) as ID, hh1.Final as Sta
	from #hist hh
	left join #hist hh1 ON (hh.ID = hh1.ID+ 1 )
	where (hh.Start is null) and not (hh1.Final is null)
	group by hh.Adres, hh1.Final

	if @@rowcount =  0  set @Cnt=  0 
	if @Cnt =  1  begin
		update #hist set Start= nn.Sta, Final= cast(round(cast(nn.Sta as real) + PlusDay,  0 ,  1 ) as smalldatetime)
		from #nav nn where (#hist.ID = nn.ID) and not (nn.Sta is null)

		truncate table #nav
	end
end
...
Рейтинг: 0 / 0
14.10.2002, 15:24:41
    #32058026
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 @pager table(id int, name varchar( 10 ), start datetime)  -- счета
 
declare @hist table(id int, paydate datetime, plus int)  -- платежи
 

insert @pager select  1 , 'Ельцин', '20010201'
        union select  2 , 'Путин', '20010401'

insert @hist select  1 , '20010101', 28 
       union select  1 , '20010102', 10 
       union select  1 , '20010502', 20 
       union select  2 , '20020102', 11 
       union select  2 , '20010502', 20 
   ----------- сам запрос -----------
 
select name 'плательщик', 
       h1.paydate 'дата платежа',
       dateadd(dd,sum(case when h1.paydate=h2.paydate then  0  else h2.plus end) ,start) 'уплачено с...' ,
       dateadd(dd,sum(h2.plus) ,start) '...по'
  from @pager p, @hist h1, @hist h2
  where p.id=h1.id and p.id=h2.id
     and h1.paydate >= h2.paydate
  group by p.id, name, h1.paydate, p.start

Кстати вызывает удивление большое количество вопросов от программистов из пейдженговых компаний. Неужели нет специальных программ? Да и как-то я не думал что у нас такая развитая пейджинговая сеть...
...
Рейтинг: 0 / 0
14.10.2002, 15:32:24
    #32058030
Luchkin Dmitry
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
2SergSuper:
Я не программист "из пейджинговой компании" и пейджинговая сеть постепенно захиревает... Но пока ещё есть и проблема не в "специальных программах", а в "специальных программах", которые удобны и могут связываться как с техническими средствами компании, так и с бухгалтерией, оставаясь удобными.
ПС. Перед Вашим видением SQL преклоняюсь . Спасибо за решение. Огромное.
PS2. Когда писал сюда вопрос, -- предполагал, что именно Вы сможете.
...
Рейтинг: 0 / 0
14.10.2002, 15:52:57
    #32058041
SergSuper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
можно ли сделать красиво...
Спасибо конечно за тёплые слова, но на самом деле тут ничего сложного нет, это обычный запрос с накоплением. Многие бы смогли написать, но мне приятно себя почувствовать умнее других, а остальные просто скромнее :)
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / можно ли сделать красиво... / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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