:: Игры Разума
Re: Вопросы не для собеседования 1
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Цитата:
order by - это не внутри, а снаружи, сортировка готового результата
Формально - да.
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
leonid
Автор

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
Таблица такая
ID_IN ID_OUT AMOUNT
1 1 5
1 2 5
2 2 2
2 3 3
2 4 15
3 4 1
3 5 4
3 6 13
3 7 6
4 7 25
А комментарии ... Ну, сначала для обеих таблиц считается, сколько уже было обработано "до того" и записывается в дополнительное поле, а затем ищутся нужные записи в виде четырех вариантов: 1. Расход забирает весь оставшийся приход. 2. Конец расхода не полностью забирает весь приход. 3. Весь расход помещается в один приход. 4. Весь приход помещается в один расход.
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Леонид, таблица правильная. По комментарию: сначала, видимо, считается сумма (по количеству) нарастающим итогом (в вашем варианте - без учета текущей строки)...

Теперь приведу свой вариант (MS SQL). Извиняюсь, срочная работа, комментарии, если надо, будут позже.

create table #Incoming (id int, amount int)
create table #Outcoming (id int, amount int)
insert #Incoming values (1, 10)
insert #Incoming values (2, 20)
insert #Incoming values (3, 24)
insert #Incoming values (4, 40)
insert #Outcoming values (1, 5)
insert #Outcoming values (2, 7)
insert #Outcoming values (3, 3)
insert #Outcoming values (4, 16)
insert #Outcoming values (5, 4)
insert #Outcoming values (6, 13)
insert #Outcoming values (7, 31)
select id_in, id_out,
case when f11 < f21 then f11 else f21 end -
case when f11-f1 < f21-f2 then f21-f2 else f11-f1 end as amount
from (select a.id as id_in, b.id as id_out,
a.amount as f1, b.amount as f2,
(select sum(a1.amount)
from #Incoming a1
where a1.id <= a.id) as f11,
(select sum(b1.amount)
from #Outcoming b1
where b1.id <= b.id) as f21
from #Incoming a, #Outcoming b) t
where case when f11 < f21 then f11 else f21 end -
case when f11-f1 < f21-f2 then f21-f2 else f11-f1 end > 0
order by id_in, id_out
drop table #Incoming
drop table #Outcoming
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
s28091973

Сообщений: 287
Дата регистрации: 05.04.2001
реально конечно круть. Вопрос, а разбивка на подзапросы не ускорит случаем время выполнения
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
leonid
Автор

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
Интересно, а умеет ли MS SQL оптимизировать такие запросы? Если нет, то при нескольких тысячах записей в каждой из таблиц такой запрос совсем загнется. А если умеет, интересно было бы посмотреть, как он этот запрос преобразует перед выполнением (на MS SQL такое можно посмотреть? На DB2 можно). Вообще было бы интересно сравнить оба варианта по скорости. Что-то мне сдается, что на больших и средних таблицах мой вариант будет значительно побыстрее.
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
s28091973

Сообщений: 287
Дата регистрации: 05.04.2001
И я о том же
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
Цитата:
разбивка на подзапросы не ускорит случаем время выполнения
Ускорит, именно на больших объемах - сильно ускорит. В рабочей процедуре сначала вычисляются итоговые суммы (нарастающие итоги), а затем уже идет расчет связей. Ну и, кроме того, в рабочей версии идет соединение по коду товара и складу, в некоторых случаях еще дополнительные условия.
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
leonid
Автор

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
А, стало быть условие уложиться в один селект было чисто академическим. Вообще при больших объемах суммы лучше считать не селектом, а создавать курсор и пробегать по нему последовательно. Тогда текущая сумма будет складываться из двух значений: текущего значения и суммы от предыдущего, а не как в селекте как сумма всех предыдущих значений (собственно именно на это обращал внимание ssa). Но писать такое, конечно, намного муторнее.
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
Prudivus

Сообщений: 4283
Откуда: Кишинев
Дата регистрации: 14.12.2006
leonid
Не просто муторнее, а практически нереально (тормоза - жуть) в хранимых процедурах на MS SQL. Но - голь на выдумки хитра ;) - есть другие методы. Например:

-- 1.4.1. расчет набегающего остатка
set @товар = null
set @склад = null
update #приход set
@tot = case when @товар = товар and @склад = получатель
then @tot+остаток else остаток end,
f11 = @tot, @товар = товар, @склад = получатель
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
Влад Колосов

Сообщений: 22664
Откуда: Ростов-на-Дону
Дата регистрации: 05.05.2005
Для сравнения - процедура расчета услуг на курсорах работает 22 часа, на селектах - 2.5 минуты. Недавно переписывал чужие труды Курсоры - ориентировочно до 1000 записей...
Использовать подзапросы выгодно тогда, когда объем результата значительно меньше основной таблицы. Хотя бы раз в 10.
Кроме того, я эмпирически получил некое соотнешение 1 гигабайт на 1 миллион Гигабай оперативки, миллион записей.
Если превысить в какой-либо операции этот объем, MS SQL загибается на составных селектах.
Поздапросы использовать более выгодно и вместо джойна с фильтром, также быстрее работает.


------------------
Совершенство - это не тогда, когда нельзя
ничего прибавить, а тогда, когда нечего убавить.
Ratings: 0 negative/0 positive
Re: Вопросы не для собеседования 1
leonid
Автор

Сообщений: 3202
Откуда: Рига
Дата регистрации: 03.02.2006
Влад Колосов
Для сравнения - процедура расчета услуг на курсорах работает 22 часа, на селектах - 2.5 минуты.
Я знаю, что курсоры работают медленее, но в том примере, о котором я говорил, при использовании курсоров нужно провести значительно (в тысячи раз) меньше операций, чем при использовании селекта. За счет этого может быть выигрыш. А реально это узнать можно только проверив.

Цитата:
Поздапросы использовать более выгодно и вместо джойна с фильтром, также быстрее работает.
Не знаю, как MS SQL, давно на нем не работал, уже забыл все, а DB2, перед тем, как выполнить запрос, практически всегда заменяет подзапрос на джойн с фильтром.
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 4 (Гостей: 4)

© 2000-2024 Fox Club 
Яндекс.Метрика