1차량 테이블
차량명 | 차량 무게량 |
1 | 100 |
2 | 150 |
3 | 200 |
2상품
상품명 | 무게 |
1 | 20 |
2 | 50 |
3 | 60 |
4 | 20 |
5 | 30 |
6 | 50 |
7 | 20 |
8 | 50 |
이와 같은 테이블에
차량에 물건을 실을 수 있는 만큼 배분하여 차량에 배정하고 싶습니다
하지만 한차량에 물건수가 몰아 지지 않게 무게가 작은순으로 순차적으로 초과무게가 넘지않게
배정하고자 하는 정보를 알수 있는 쿼리를 만들고 싶습니다
조언좀 부탁드립니다
Comment 1
-
minsouk
2015.07.17 18:13
이런 로직은 최대한 유연하게 짜는게 좋을듯 합니다.
조건이 언제든지 바뀔 수 있기 때문에 프로그램적인 로직이 잘 녹아 들어갈 수 있게 짜는게 좋을듯 합니다.
상품이 3개 있을때도 적절하게 배분되어야 들어가야 하고
상품이 100개 있을때도 적절히 분배 되어야 들어가야 한다라고 이해 하고 구현해 봤습니다.
차량이 3대라면 3번 돌리죠 뭐~
데이터는 이렇게 만들었어요
select productKey, avg(cast(UnitPrice as int)) productWeight into 상품
from [dbo].[FactResellerSales]
group by productKey
go
alter table 상품 add carNum int
go
아래는 프로시저로 구현하면 되겠죠?
declare @modNum int
declare @limitWeight int
declare @carNum int
select @modNum = 3, @limitWeight = 100, @carNum = 1
--select @modNum = 2, @limitWeight = 150, @carNum = 2
--select @modNum = 1, @limitWeight = 200, @carNum = 3
;with cte_partition
as
(
select *
from (
select row_number() over (order by productWeight) rn
, productKey
, productWeight
from 상품
where carNum is null
) a
where rn % @modNum = 0
)
, targetProduct
as
(
select *
from cte_partition a
cross apply
(select sum(productWeight) productWeightLimit
from cte_partition b
where b.rn <= a.rn
) b
where productWeightLimit < @limitWeight
)
update t
set carNum = @carNum
from targetProduct a
join 상품 t
on a.productKey = t.productKey
이런 절차를 3번 합니다.
update 상품 set carNum = null
select @modNum = 3, @limitWeight = 100, @carNum = 1
select @modNum = 2, @limitWeight = 150, @carNum = 2
select @modNum = 1, @limitWeight = 200, @carNum = 3
select carNum, count(*) 상품차량배당현황
from 상품
where carNum is not null
group by carNum
요즘 쿼리짤일이 없어서 한번 해봤어요
2012 부터는 running summary 구하는 function 이 따로 지원됩니다. 2012 이상이면 해당 함수를 써도 좋을듯 하구요