Гость
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / маленькая задачка / 25 сообщений из 29, страница 1 из 2
07.10.2003, 09:47
    #32285793
Aleksey777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Здравствуйте !!!
Помогите решить следующую задачку средствами SQL

Есть таблица1
с данными
А 1 10
А 2 12
А 3 2
А 4 5

И таблица 2 с данными
А 25

необходимо получить таблицу 3
А 1 10
А 2 12
А 3 2
А 4 1
...
Рейтинг: 0 / 0
07.10.2003, 09:57
    #32285813
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
select 'А', 1, 10,
union
select 'А', 2, 12
union
select 'А', 3, 2
union
select 'А', 4, 1
или в чем закономерность ?
...
Рейтинг: 0 / 0
07.10.2003, 10:00
    #32285816
Aleksey777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
необхимо получить таблицу 3 по выборке из таб 1 и 2
т.е. во второй таблице указан товар "А" и кол-во 25
а в первой таблице есть Товар, Номер партии, Кол-во в партии.
Вот и надо получить таблицу 3, данные в таблице 1 и 2 могут быть произвольные естественно.
Извиняюсь за непонятную постановку вопроса.
...
Рейтинг: 0 / 0
07.10.2003, 10:10
    #32285825
Berg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Имхо понятнее не стало...Так что же должно быть не в 1-й и не во 2-й таблице, а в самой что ни на есть 3-ей?
...
Рейтинг: 0 / 0
07.10.2003, 10:12
    #32285827
Glory
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
declare @t1 table(f1 char( 1 ), f2 int, f3 int)

insert @t1 
select 'A',  1 ,  10 
union 
select 'A',  2 ,  12  
union 
select 'A',  3 ,  2  
union 
select 'A',  4 ,  5 

declare @t2 table(p1 char( 1 ), p2 int)

insert @t2
select 'A',  25 

select * from(
select a.f1, a.f2, max(a.f3)+sum(isnull(b.f3,  0 )) as tot_sum
from @t1 a
left outer join @t1 b on b.f1=a.f1 and b.f2 < a.f2
group by a.f1, a.f2, a.f3
) AS a
inner join @t2 b on b.p1 = a.f1 and b.p2 > a.tot_sum
...
Рейтинг: 0 / 0
07.10.2003, 10:15
    #32285835
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
кажется я догадался, и если догадка верна, то запросом никак, придется в цикле добавлять по записи и проверять на сумму

никак - потому, что записи невозможно разбить на произвольное, но конечное количество групп, объединив их в юнион, чтобы в последнем селекте юниона добавить недостающий остаток

вобщем задача нереляциооная - подбор в чистов виде, а значит итерации

вариант циклом тоже вызывает затруднение?
...
Рейтинг: 0 / 0
07.10.2003, 10:20
    #32285847
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
посмотрел вариант Glory, решил подробнее описать свою догадку:

в таблице 2 - желаемый товар и кол-во, в таблице 3 - список партий из таблицы 1, количество в которых может быть уменьшено так, чтобы в сумме было число из таблицы 2

если это так - то только цикл
...
Рейтинг: 0 / 0
07.10.2003, 10:21
    #32285848
Berg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Это а-ля knapsack задача? На T-SQL? И чтобы быстро? Уже интересно...
Или просто последний кусок на части разбить надо?
...
Рейтинг: 0 / 0
07.10.2003, 10:25
    #32285858
MiCe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
какие партии должны выбираться? те что пришли раньше или позже?
нужно четче поставить задачу..... думаю что партию можно использовать и частично....
...
Рейтинг: 0 / 0
07.10.2003, 11:14
    #32285947
Павел Воронцов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Код: 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.
declare @party table (
                  good_code char( 1 ) not null,
                  party_id int not null identity( 1 , 1 ) primary key,
                  quantity int not null check (quantity >  0  ),
                  party_date datetime default getdate() not null
)
declare @good table (
                 good_code char( 1 ) not null primary key,
                 quantity int not null check (quantity >  0  )
)
insert into @party (good_code, quantity,party_date)
values ('A', 10 ,getdate()- 3 )
insert into @party (good_code, quantity,party_date)
values ('A', 12 ,getdate()- 2 )
insert into @party (good_code, quantity,party_date)
values ('A', 2 ,getdate()- 1 )
insert into @party (good_code, quantity,party_date)
values ('A', 5 ,getdate())

insert into @good (good_code, quantity)
values ('A', 25 )

select * from @party
select * from @good

select p.*, case sign(g.quantity - (select sum(p1.quantity) 
                                      from @party p1
                                      where p1.good_code = p.good_code
                                            and p1.party_date <= p.party_date))
             when  1  then p.quantity
             when  0  then p.quantity
             else (g.quantity - (select sum(p1.quantity) - p.quantity
                                      from @party p1
                                      where p1.good_code = p.good_code
                                            and p1.party_date <= p.party_date))
             end as q
from @party p inner join @good g on p.good_code = g.good_code
                   and g.quantity >= (select sum(p1.quantity) - p.quantity
                                      from @party p1
                                      where p1.good_code = p.good_code
                                            and p1.party_date <= p.party_date)
...
Рейтинг: 0 / 0
07.10.2003, 11:21
    #32285965
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
не пугай, а
я конечно проверил из любопытства (а сам то смотрел на результат? - он не отличается от входных данных), но кажется чудес не бывает
...
Рейтинг: 0 / 0
07.10.2003, 11:24
    #32285971
Aleksey777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
2 iSestrin: догадался.
2 MiCe: не важно в каком порядке партии, сейчас важно, что можно ли запросом бить последнюю расходуемую.
2 Павел Воронцов: спасибо за пример, сейчас поразбираюсь.
...
Рейтинг: 0 / 0
07.10.2003, 11:27
    #32285978
Aleksey777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
2: Павел Воронцов похоже, но когда ровное количество, в данном примере 22 или 24, то добавляется последняя с нулевым количеством.
...
Рейтинг: 0 / 0
07.10.2003, 11:34
    #32285986
Aleksey777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
2: Павел Воронцов, лечится если в коде
from @party p inner join @good g on p.good_code = g.good_code
and g.quantity >= (select sum(p1.quantity) - p.quantity
from @party p1
where p1.good_code = p.good_code
and p1.party_date <= p.party_date)

заменить на
and g.quantity > (select sum(p1.quantity) - p.quantity
...
Рейтинг: 0 / 0
07.10.2003, 11:41
    #32286002
Павел Воронцов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
iSestrin
Шо, страшно? Я ещё и крестиком могу..

Aleksey777
Да, похоже, что так.
...
Рейтинг: 0 / 0
07.10.2003, 11:45
    #32286013
Aleksey777
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
2: Павел Воронцов. Спасибо !!!
...
Рейтинг: 0 / 0
07.10.2003, 11:51
    #32286027
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
2 Павел Воронцов
работа великолепная, но ... я нашел ошибку, или скажем так - вариант входных данных, на которых это не работает (например повтори одну партию с кол-м = 1 раз 30, и все ломается)

потому и остаюсь при своем мнении
...
Рейтинг: 0 / 0
07.10.2003, 12:02
    #32286041
Павел Воронцов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
iSestrin
Да Бога ради, оставайся при своём мнении, я не в обиде! ) А вот набор данных, на котором ломается - приведи пожалуйста. Желательно код. Заранее благодарен.
...
Рейтинг: 0 / 0
07.10.2003, 12:09
    #32286052
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
вот это место:

insert into @party (good_code, quantity,party_date)
values ('A',10,getdate()-3)
insert into @party (good_code, quantity,party_date)
values ('A',12,getdate()-2)
insert into @party (good_code, quantity,party_date)
values ('A',2,getdate()-1)
insert into @party (good_code, quantity,party_date)
values ('A',5,getdate())

меняем на

insert into @party (good_code, quantity,party_date)
values ('A',1,getdate())

повторенное, как я уже сказал, раз 30, чтоб хватило, но скорее всего это не важно

т.е. важен принцип - при совпадении партий - не работает
...
Рейтинг: 0 / 0
07.10.2003, 12:24
    #32286079
Павел Воронцов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
iSestrin
дело стало быть в следующем. Я предполагал (жаль, в констрейнты это не внёс для пущей ясности), что партии отличаются по датам появления. Строка
insert into @party (good_code, quantity,party_date)
values ('A',1,getdate())

повторееная несколько раз добавит записи с АБСОЛЮТНО ОДИНАКОВЫМИ датами (это фича сервера - он дёргает getdate один раз, оптимизатор хренов..) - проверьте сами. В принципе запрос можно переписать, заложившись на последовательность идентификаторов партий, но лень да и незачем.
...
Рейтинг: 0 / 0
07.10.2003, 12:45
    #32286135
iSestrin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
wow! это я погорячился ...
собственно getdate() он дергает много раз, просто ее дискрет кажется 0.003, потому совпадает, но это не важно...

меняю свое мнение на прямо противоположное:)
респект!
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
07.04.2020, 16:49
    #39944596
Алексей.
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
День добрый!
Очень понравилось решение этой задачки, предложенное Павлом Воронцовым.
Вопрос к знатокам SQL: а можно ли его применить для решения более сложной задачи - последовательного распределения по партиям не одной, а нескольких сумм (c сохранением информации не только о том, в каком размере партия "закрыта", но и какой именно из сумм и в каком объеме)?
Сложность в таком случае возникает из-за возможности закрытия 1 партии частями разных сумм из goods.

Указанную в решении таблицу good вижу для себя примерно как-то так:

declare @good table (
good_code char(1) not null,
good_row_id int not null identity(1,1) primary key,
quantity int not null check (quantity > 0 )
)

ожидаемый результат:
party_id / quantity / party_date / good_row_id / q

К сожалению, у меня выходит решить эту задачу только последовательными итерациями, а хотелось бы элегантного решения 1 запросом. Возможно ли такое?
...
Рейтинг: 0 / 0
07.04.2020, 17:17
    #39944603
Владислав Колосов
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Алексей.,

А какого объема данные? ИМО данные будет быстрее загрузить в C# масссив и разложить алгоритмически, чем учить лягушку разговаривать. Можно оформить табличной CLR функцией.
...
Рейтинг: 0 / 0
07.04.2020, 17:23
    #39944606
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
...
Рейтинг: 0 / 0
07.04.2020, 21:00
    #39944657
Алексей.
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
маленькая задачка
Владислав Колосов,

Хотелось узнать о возможности решения именно средствами стандартного SQL.
Но в любом случае, спасибо за информацию )
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / маленькая задачка / 25 сообщений из 29, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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