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

Откуда:
Сообщений: 8
Подскажите пожалуйста, как можно решить такую задачку. Имеется таблица:

codealtcodeprice
.........
1a1aa10$
1aa2a16$
2a14$
.........


Суть в том что артикул 1а меняется на артикул 1аа, который в свою очередь меняется на 2а и у них у всех разные цены, а люди просят сделать у каждой такой цепочки в таблице максимальную цену из всех имеющихся в соответствующей цепочке. В приведенном примере всем нужно проставить 16$

Заранее большое спасибо за любые идеи :)
19 ноя 14, 04:04    [16869149]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Klemzig
Guest
woodl,

Про рекурсивное CTE слыхали?

Только вот, не очень понятна логика, если у вас там в цепочках ветвления будут. Ну например, добавляем строку:

1aa 3a 21$
- какая теперь должна быть цена у 2a?
19 ноя 14, 05:34    [16869182]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
aleks2
Guest
Klemzig
какая теперь должна быть цена у 2a?

Цена всегда должна быть МАКСИМАЛЬНОЙ.
19 ноя 14, 05:59    [16869191]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
woodl,
можно через рекурсивный cte
USE tempdb
GO

declare @t table (code int, altcode int, m money)

insert @t (code,altcode,m)
values (1,11,15.10), (11,111,18),(111,1111,11.3)
	  ,(2,22,3),(22,222,100)
	  ,(3,null,15)

;with cte as
(
select code codeGlobal, altcode, m
from @t t
where not exists (select * from @t t2 where t.code=t2.altcode)
UNION ALL
select c.codeGlobal, t.altcode, t.m
from @t t
	 join cte c ON c.altcode=t.code
)
select codeGlobal, MAX(m)
from cte
group by codeGlobal
19 ноя 14, 06:45    [16869218]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8317
Зачем использовать рекурсию для поиска максимальной цены?
Надо использовать объединение с той же таблицей по колонкам code и altcode.
19 ноя 14, 12:39    [16870909]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Ruuu
Member

Откуда: Иркутск
Сообщений: 4272
Владислав Колосов,

Насколько я понял задачу: это дерево, число уровней зависимости неизвестно, надо найти максимальную сумму из всех зависимых узлов для корневого узла.

Что-то не приходит в голову как это сделать через "объединение с той же таблицей".
19 ноя 14, 12:52    [16871039]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8317
Ruuu, да, действительно.
19 ноя 14, 15:24    [16872483]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
Klemzig,

у нас в первой колонке не может быть повторяющихся артикулов с разными ценами
20 ноя 14, 17:56    [16880683]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
Ruuu,

большое спасибо за пример! Суть понятна, попробую сейчас переделать чтобы на выходе было то что мне нужно :)
20 ноя 14, 18:28    [16880926]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
Господа!

На реальном прайс-листе из почти 300 тысяч позиций такой запрос выполняется уже 30 минут :) Можно его как-то оптимизировать?

with cte as
(
select code codeGlobal, code, altcode, price
from _bmw t
where not exists (select * from _bmw t2 where t.code=t2.altcode)
UNION ALL
select c.codeGlobal, t.code, t.altcode, t.price
from _bmw t
	 join cte c ON c.altcode=t.code
)
update _bmw
set CodeGlobal = c.codeGlobal
from _bmw as t
inner join cte c on t.code=c.code
go
21 ноя 14, 18:25    [16887292]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Glory
Member

Откуда:
Сообщений: 104760
woodl
На реальном прайс-листе из почти 300 тысяч позиций такой запрос выполняется уже 30 минут

а что вы собственно хотели сделать этим апдейтом ?
21 ноя 14, 22:12    [16888112]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
Glory,

В исходной таблице добавляю колонку по которой можно будет идентифицировать группу взаимозаменяемых деталей



PS Прошло почти 4 часа, запрос все еще выполняется :)
21 ноя 14, 22:27    [16888145]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
Glory
Member

Откуда:
Сообщений: 104760
woodl
В исходной таблице добавляю колонку по которой можно будет идентифицировать группу взаимозаменяемых деталей

апдейт не добавляет колонок
Вы понимаете, что вы свои 300 тысяч позиций увеличили в N раз и потом опять соединяете с теми же 300 тысячью позиций ?
Вы реально думаете, что в этом есть смысл ?
21 ноя 14, 22:43    [16888201]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
Glory,

я понимаю что это рекурсия и позиций много, но другого выхода я не вижу пока к сожалению. На тестовой табличке все корректно отработало, бесконечную рекурсию sql сервер прерывает, значит есть надежда что все правильно и получение нужного результата это вопрос времени. С радостью послушал бы другие идеи как решить поставленную задачу!
21 ноя 14, 23:05    [16888278]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
aleks2
Guest
woodl
Glory,

я понимаю что это рекурсия и позиций много, но другого выхода я не вижу пока к сожалению. На тестовой табличке все корректно отработало, бесконечную рекурсию sql сервер прерывает, значит есть надежда что все правильно и получение нужного результата это вопрос времени. С радостью послушал бы другие идеи как решить поставленную задачу!


declare @t table (code int, altcode int, m money, maxm money, src_code int)

insert @t (code,altcode,m) values (1,11,15.10)
insert @t (code,altcode,m) values (11,111,18)
insert @t (code,altcode,m) values (111,1111,11.3)
insert @t (code,altcode,m) values (2,22,3)
insert @t (code,altcode,m) values (22,222,100)
insert @t (code,altcode,m) values (3,null,15)

-- вот дай дураку фантик

declare @rc int

update t set maxm = m, src_code = code
  from @t t;

set @rc = @@rowcount;

while @rc > 0
begin
  update t set maxm = tt.maxm, src_code = tt.src_code
    from @t t inner join @t tt on t.altcode = tt.code and tt.maxm > t.maxm;
  set @rc = @@rowcount;
end;

select * from @t;
22 ноя 14, 08:21    [16888989]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
aleks2,

приведенный код не приводит таблицу к нужному результату, в строке с кодом 111 цена должна быть 18, а она остается прежней.
22 ноя 14, 22:23    [16890888]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
aleks2
Guest
woodl
aleks2,

приведенный код не приводит таблицу к нужному результату, в строке с кодом 111 цена должна быть 18, а она остается прежней.


Клиент недоволен?
Я сделал как сказано "артикул 1а меняется на артикул 1аа, который в свою очередь меняется на 2а".

Ну, если вам нужно распространение цен в "другую сторону" - ну поправьте условие соединения join.
Если вам нужно распространение цен в "обе стороны" - ну добавьте еще один while.
24 ноя 14, 08:22    [16894297]     Ответить | Цитировать Сообщить модератору
 Re: нужна помощь  [new]
woodl
Member

Откуда:
Сообщений: 8
aleks2,

спасибо за Ваш вариант!
24 ноя 14, 12:33    [16895704]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить