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

Откуда: USSR
Сообщений: 267
Третий день бьюсь и никак не найду нормальный выход из положения.
Проблемма в том что я никак не пойму можно ли сделать такой запрос или нет, а второе если нет то где будет быстрее эта обработка, на сервере или сделать в программе?
Суть вот в чем, есть у меня список материалов, на каждый материал может быть adjustment (правка) и могут быть также additions (дополения по цене или кол-ву материала. Сортируются они в таком плане
1. По дате проема
2. По Номеру докумета
3. По типу записи 0-материал, 1,2=исправление, 3-дополнение
4. Sequnce number - последовательный номер для записей.

С 4 разьясню подробнее. К примеру если есть документ с номером 1500, то каждый материал в этом джокументе по ходу записи получает порядковый номер 1,2,3 и т.д. Для каждого материала (см. выше) могут потом дописыватся изменения или дополнения, они тоже получают свои порядковые номера. В итоге чтобы получить список материалов и их дополнений/изменений в той последователньости в которой они принимались (на складе), используются эти номера в сортировке.
Пример
Материал Тип Записи seq_num
255 0 1
255 1 1
255 1 2
255 2 1
255 2 2
255 3 1
255 3 2
255 3 3
и так далее.
Теперь вот в чем проблемма то, мне нужно найти предыдущую запись для любой выбранной записи!!! Это используется для перерасчет кол-ва, средней цены и так далее, не важно для чего. Так как записей может быть очень много делать это через курсор и последовательно идти до нужного номера жутко медленно, делатьтоже самое в программе (я пишу на Дельфи) через Query и двигаться до нужного номера еще медленнее. Хочется сделать запрос и чтобы он вернул именно ту запись которая по сортировке будет назходиться раньше чем выбранная. Есть уникальный ID записи, но он абсолютно не используется в сортировке, так как Исправления/Дополнения могут вводиться через месяц после регистрации материала, а по сути должны следовать сразу после материала. Наверное очень жутко обьяснил. Но у меня глова уже пухнет. Я не ньюб в этом деле с 1990 года занимают програмингом с базами. Но вот тут просто сел и ничего не могу поделать. 8-((( Помогите советом чтоли, в каком направлении двигаться
9 сен 03, 11:26    [331130]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Если мне изменяет память, то всё это как то напоминает партионный учет. Если так, то туда и двигать.
9 сен 03, 11:39    [331172]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
партионный учет Что сие есть такое?
9 сен 03, 11:48    [331193]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2386
Блог
Я совсем не уверен, что понял задачу правильно. Насколько я могу судить по описанию, по заданным @id, @type, @seq_num нужно найти предыдущую по seq_num запись? Тогда почему не

select *
from table
where id = @id and
type = @type and
seq_num = @seq_num -1

?
9 сен 03, 12:08    [331263]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Luchkin Dmitry
Member

Откуда: Новосибирск -> Ангарск -> Братск -> Мск
Сообщений: 1921

--1. По дате проема

--2. По Номеру докумета

--3. По типу записи 0-материал, 1,2=исправление, 3-дополнение

--4. Sequnce number - последовательный номер для записей.


--надо найти предыдущую запись к записи %af_src_str_0, %af_src_str_1, 255, 2, 2

declare @vDate smalldatetime, @vNDoc varchar(20), @vMater int, @vTip int, @vSeq int

set @vDate= '20030909'
set @vNDoc= '1'
set @vMater= 255
set @vTip= 2
set @vSeq= 2

-- создаём эту хрень

create table #t (ID int IDENTITY (1, 1) NOT NULL,
data smalldatetime, ndoc varchar(20),
mater int, tip int, Seq int)

insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 0, 1)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 1, 1)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 1, 2)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 2, 1)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 2, 2)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 3, 1)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 3, 2)
insert #t (data, ndoc, mater, tip, Seq) VALUES('20030909', '1', 255, 3, 3)

select top 1 * from #t
where (data = @vDate) and (ndoc = @vNDoc) and -- документ должен быть тем же anyway

mater <= @vMater and tip <= @vTip and seq <= @vSeq
and not (mater = @vMater and tip = @vTip and seq = @vSeq)
order by 2, 3, 4 desc, 5 desc, 6 desc

drop table #t
9 сен 03, 12:12    [331274]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
Блин совсем забыл что еще данные по типу записи и seq_num могу повтрояться для разных номеров документа!

Master_ID Rec_Type Seq_NUM
100 0 1
100 0 2
100 0 3
100 1 1
100 2 1
100 3 1
100 3 2
100 3 3
101 0 1
102 0 2
102 0 3
102 3 1
102 3 2
103 0 1
104 0 2

Что очень сильно усложняет запрос
9 сен 03, 13:00    [331408]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
документ должен быть тем же anyway
Вот тут загвозка, если для документа это первая и единственная запись, то прошлая для нее будет это запись для предыдущего документа.
9 сен 03, 13:02    [331421]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Luchkin Dmitry
Member

Откуда: Новосибирск -> Ангарск -> Братск -> Мск
Сообщений: 1921
ну попробуй и с док-том тоже
типа:

select top 1 * from #t
where data <= @vDate and ndoc <= @vNDoc and
mater <= @vMater and tip <= @vTip and seq <= @vSeq
and not (data = @vDate and ndoc = @vNDoc and mater = @vMater and tip = @vTip and seq = @vSeq)

order by 2 desc, 3 desc, 4 desc, 5 desc, 6 desc


скажи потом, получилось или нет ;)
9 сен 03, 13:09    [331442]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
and tip <= @vTip and seq <= @vSeq

Если vTip всегда бьудет <= то вот с vSeq нет, он может и должен быть меньше если vTip = выбранному или любой последний если vTip < выбранного.
9 сен 03, 14:24    [331666]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Luchkin Dmitry
Member

Откуда: Новосибирск -> Ангарск -> Братск -> Мск
Сообщений: 1921
типа такого?

select top 1 * from #t
where
data <= @vDate and
(ndoc <= @vNDoc or data < @vDate) and
(mater <= @vMater or data < @vDate or (data = @vDate and ndoc <@vNDoc)) and
(tip <= @vTip or data < @vDate or (data = @vDate and ndoc <@vNDoc)) and
(seq <= @vSeq or data < @vDate or (data = @vDate and ndoc <@vNDoc))
and not (data = @vDate and ndoc = @vNDoc and mater = @vMater and tip = @vTip and seq = @vSeq)
order by 2 desc, 3 desc, 4 desc, 5 desc, 6 desc


в общем, путь ясен. остальное дело техники и отсутствия лени имхо
9 сен 03, 14:43    [331736]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
Сенкс, пытаюсь вот пробую, пока ничего не получается :(
Запрос пашет но возвращает не правильно данные когда номера документов разные
9 сен 03, 15:51    [331897]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Luchkin Dmitry
Member

Откуда: Новосибирск -> Ангарск -> Братск -> Мск
Сообщений: 1921
ну дай скрипт с созданием таблицы и загоном в неё данных. лень самому придумывать. причём именно эти, на которых затыкается. если что-то не верно работает, значит не до конца логику прописал. сильно-то задумываться не охота...
9 сен 03, 16:03    [331924]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
Мне не лень, на голова пухнет уже. Целый день сидиш на работе над одним запросом это ужасно.
Сейчас вот наткнулся на грабли с номером документа, если разрешу его в плане правильного ввода, то все будет окей, иначе фиинита.
9 сен 03, 16:16    [331956]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Luchkin Dmitry
Member

Откуда: Новосибирск -> Ангарск -> Братск -> Мск
Сообщений: 1921
да не тебе лень ;) эт я про себя. говорю-ж, скинь скрипт, мы быстренько найдём, что к чему
9 сен 03, 16:25    [331982]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
Под общим принципом разобрался уже, пришлось в самой программе ввести кучу ограничений чтобюы небыло конфликтов и повторений, и соответственно запрос получился очень простым

select * from rec_det
where
rec_date <= @vDate and
id<>@id and
(
(master_id=@vmaster_id and rec_type=@vrec_type and seq_num<@vseq_num)
or
(master_id=@vmaster_id and rec_type<@vrec_type)
or
(master_id<@vmaster_id)
)
and
item_code=@vitem_code
order by rec_date desc, master_id desc, rec_type desc, seq_num desc
9 сен 03, 17:05    [332095]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
SandalTree
Member

Откуда: Перехлёсток восьми батог
Сообщений: 28146
Может так заработает?

create table #M(m int, t int, s int, id int identity(1,1) )


insert into #M
select 255, 0, 1 union
select 255, 1, 1 union
select 255, 1, 2 union
select 255, 2, 1 union
select 255, 2, 2 union
select 255, 3, 1 union
select 255, 3, 2 union
select 255, 3, 3

select * from #m order by id

select * from #m where id = 4

declare @ID int
set @ID = 4

select top 1 m1.*
from #m m1
inner join #m m2
on ((m2.t = m1.t and m2.s > m1.s) or m2.t > m1.t)
and m2.m = m1.m
where m2.id = @ID
order by m1.t desc, m1.s desc

drop table #M
9 сен 03, 18:16    [332252]     Ответить | Цитировать Сообщить модератору
 Re: Не дайте повесится , запрос делать или на программе?  [new]
Ray Adams
Member

Откуда: USSR
Сообщений: 267
Все спасибо за участия я все же написал его сам, но не без вашей помощи. Идеи так сказать появились , после просмотра вариантов.
9 сен 03, 22:57    [332505]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить