5개의 컬럼 데이터를 조합하여 13가지의 경우의 수를 대입하여 1개~최대 13개까지 로우가 나올수 있습니다
Declare @Temp Table
(
몸체A품번 Int, 몸체A품명 varchar(10), 몸체A수량 int,
몸체B품번 Int, 몸체B품명 varchar(10), 몸체B수량 int,
A타입품번 Int, A타입품명 varchar(10), A타입수량 int,
B타입품번 Int, B타입품명 varchar(10), B타입수량 int,
날개품번 Int, 날개품명 varchar(10), 날개수량 int
);
Insert Into @Temp Values (1,'몸체A',10, 2,'몸체B',3, 3,'A타입',5, 4,'B타입',12, 5,'날개',43);
Insert Into @Temp Values (1,'몸체A',20, 2,'몸체B',10, 3,'A타입',10, 4,'B타입',5, 5,'날개',12);
Insert Into @Temp Values (1,'몸체A',20, 2,'몸체B',18, 3,'A타입',5, 4,'B타입',10, 5,'날개',50);
Select * From @Temp;
/* 적용할 순서 - 최고 적은수량이 수량이됨
1. 몸체A(1EA)+ A타입(1EA)+ 날개(2EA)
2. 몸체B(1EA)+ A타입(1EA)+ 날개(2EA)
3. 몸체A(1EA)+ B타입(1EA)+ 날개(2EA)
4. 몸체B(1EA)+ B타입(1EA)+ 날개(2EA)
5. 몸체A(1EA)+ A타입(1EA)
6. 몸체B(1EA)+ A타입(1EA)
7. 몸체A(1EA)+ B타입(1EA)
8. 몸체B(1EA)+ B타입(1EA)
9. 몸체A(1EA)
10. 몸체B(1EA)
11. A타입(1EA)
12. B타입(1EA)
13. 날개(1EA)
*/
1개의 Row로 13가지의 경우수를 차례대로 대입 차감하여 경우의 수를 모두 Row로 표시해줘야합니다.
1개가 나올수 있고 여러개의 Row가 나올수 있습니다.
대입은 몸체A (1EA): 몸체B (1EA): A타입(1EA) : B타입(1EA): 날개(2EA) 로 날개는 2개씩 차감해야합니다.
해당 경우의 최소갯수가 해당 경우의수의 수량입니다.
- 몸체A(1EA)+ A타입(1EA)+ 날개(2EA) = 10개+ 5개+ 21개(43개/2) = 5개
A타입이 5개로 다른제품이 많아도 5개가됩니다.
경우의수가 많아서 커서를 활용해볼까 했는데 커서를 사용하지 않고 가능할것 같은데
좋은 방법이 생각이 안나네요 몇일동안 생각을 해봐도 떠오르질 않네요
--1. 몸체A 10개, 몸체B 3개, A타입 5개, B타입 12개, 날개 43개 일경우
1. 몸체A(1EA)+ A타입(1EA)+ 날개(2EA) = 10개+ 5개+ 21개(43개/2) = 5개
2. 몸체B(1EA)+ A타입(1EA)+ 날개(2EA) = 3개+ 0개+ 16개(33개/2) = 0개
3. 몸체A(1EA)+ B타입(1EA)+ 날개(2EA) = 5개+ 12개+ 16개(33개/2) = 5개
4. 몸체B(1EA)+ B타입(1EA)+ 날개(2EA) = 3개+ 7개+ 11개(23개/2) = 3개
5. 몸체A(1EA)+ A타입(1EA) = 0개+ 0개+ = 0개
6. 몸체B(1EA)+ A타입(1EA) = 0개+ 0개+ = 0개
7. 몸체A(1EA)+ B타입(1EA) = 0개+ 4개+ = 0개
8. 몸체B(1EA)+ B타입(1EA) = 0개+ 4개+ = 0개
9. 몸체A(1EA) = 0개
10. 몸체B(1EA) = 0개
11. A타입(1EA) = 0개
12. B타입(1EA) = 4개
13. 날개(1EA) = 17개
--2. 몸체A 20개, 몸체B 10개, A타입 10개, B타입 5개, 날개 12개 일경우
1. 몸체A(1EA)+ A타입(1EA)+ 날개(2EA) = 20개+ 10개+ 6개(12개/2) = 6개
2. 몸체B(1EA)+ A타입(1EA)+ 날개(2EA) = 10개+ 4개+ 1개(2개/2) = 1개
3. 몸체A(1EA)+ B타입(1EA)+ 날개(2EA) = 14개+ 5개+ 0개(0개/2) = 0개
4. 몸체B(1EA)+ B타입(1EA)+ 날개(2EA) = 9개+ 5개+ 0개(0개/2) = 0개
5. 몸체A(1EA)+ A타입(1EA) = 14개+ 3개+ = 3개
6. 몸체B(1EA)+ A타입(1EA) = 9개+ 0개+ = 0개
7. 몸체A(1EA)+ B타입(1EA) = 11개+ 5개+ = 5개
8. 몸체B(1EA)+ B타입(1EA) = 6개+ 0개+ = 0개
9. 몸체A(1EA) = 0개
10. 몸체B(1EA) = 0개
11. A타입(1EA) = 0개
12. B타입(1EA) = 0개
13. 날개(1EA) = 0개
--3. 몸체A 20개, 몸체B 18개, A타입 5개, B타입 10개, 날개 50개 일경우
1. 몸체A(1EA)+ A타입(1EA)+ 날개(2EA) = 20개+ 5개+ 25개(50개/2) = 5개
2. 몸체B(1EA)+ A타입(1EA)+ 날개(2EA) = 18개+ 0개+ 20개(40개/2) = 0개
3. 몸체A(1EA)+ B타입(1EA)+ 날개(2EA) = 15개+ 10개+ 20개(40개/2) = 10개
4. 몸체B(1EA)+ B타입(1EA)+ 날개(2EA) = 18개+ 0개+ 10개(20개/2) = 0개
5. 몸체A(1EA)+ A타입(1EA) = 5개+ 0개+ = 0개
6. 몸체B(1EA)+ A타입(1EA) = 18개+ 0개+ = 0개
7. 몸체A(1EA)+ B타입(1EA) = 5개+ 0개+ = 0개
8. 몸체B(1EA)+ B타입(1EA) = 18개+ 0개+ = 0개
9. 몸체A(1EA) = 5개
10. 몸체B(1EA) = 18개
11. A타입(1EA) = 0개
12. B타입(1EA) = 0개
13. 날개(1EA) = 20개
Comment 14
-
건우아빠
2013.06.25 10:49
-
다초
2013.06.25 12:03
네 맞습니다. 이해하기 쉽도록 올렸어야 했는데 정리 잘해주셔서 감사합니다^^
조인이나 인덱스에 따라서 커서가 더 좋을수도 있겠네요
답변 달아주시는거 보면 생각지 못했던 방법을 제시해주셔서 응용을 많이 하고 있습니다.
-
건우아빠
2013.06.25 13:15
테이블리턴함수로 만들어 봤습니다.
함수를 이용하지 않고 순순한 쿼리로만 하는건 잘 분석하시면 충분히 나올것도 같습니다.
쿼리는 직접 고민해 보세요 ...
/*
drop table #Job_T
go
with [Job_T] as
(
select 1 idx, '1. 몸체A(1EA)+ A타입(1EA)+ 날개(2EA)' Job_nm ,1 Bady_a,0 Bady_b,1 Type_a,0 Type_b,2 Wing , 1 u_qty union all
select 2,'2. 몸체B(1EA)+ A타입(1EA)+ 날개(2EA)',0,1,1,0,2,1 union all
select 3,'3. 몸체A(1EA)+ B타입(1EA)+ 날개(2EA)',1,0,0,1,2,1 union all
select 4,'4. 몸체B(1EA)+ B타입(1EA)+ 날개(2EA)',0,1,0,1,2,1 union all
select 5,'5. 몸체A(1EA)+ A타입(1EA)',1,0,1,0,0,1 union all
select 6,'6. 몸체B(1EA)+ A타입(1EA)',0,1,1,0,0,1 union all
select 7,'7. 몸체A(1EA)+ B타입(1EA)',1,0,0,1,0,1 union all
select 8,'8. 몸체B(1EA)+ B타입(1EA)',0,1,0,1,0,1 union all
select 9,'9. 몸체A(1EA)',1,0,0,0,0,1 union all
select 10,'10. 몸체B(1EA)',0,1,0,0,0,1 union all
select 11,'11. A타입(1EA)',0,0,1,0,0,1 union all
select 12,'12. B타입(1EA)',0,0,0,1,0,1 union all
select 13,'13. 날개(1EA)',0,0,0,0,1,1
)
select * into Job_T from [Job_T]
*/
select * from dbo.ufn_job_gong (10,3,5,12,43 )
create FUNCTION [dbo].[ufn_job_gong]
(
@Bady_a int , @Bady_b int, @Type_a int ,@Type_b int , @Wing int
)
RETURNS @Temp TABLE
( idx int
, Bady_a int
, Bady_b int
, Type_a int
, Type_b int
, Wing int
, job_qty int )
AS
BEGIN
declare @sBady_a int , @sBady_b int, @sType_a int ,@sType_b int , @sWing int
declare @job_qty int ,@i int
set @i = 0
while @i < 13
begin
set @i = @i + 1
select @job_qty = min(case c.no
when 1 then (case when b.Bady_a = 0 then NULL else @Bady_a / b.Bady_a end )
when 2 then (case when b.Bady_b = 0 then NULL else @Bady_b / b.Bady_b end )
when 3 then (case when b.Type_a = 0 then NULL else @Type_a / b.Type_a end )
when 4 then (case when b.Type_b = 0 then NULL else @Type_b / b.Type_b end )
when 5 then (case when b.Wing = 0 then NULL else @Wing / b.Wing end )
end)
from Job_T b , ( select 1 no union all select 2 no union all select 3 no union all select 4 no union all select 5 no ) c
where b.idx = @i
select @sBady_a = Bady_a * @job_qty
, @sBady_b = Bady_b * @job_qty
, @sType_a = Type_a * @job_qty
, @sType_b = Type_b * @job_qty
, @sWing = Wing * @job_qty
from Job_T
where idx = @i
set @Bady_a = @Bady_a - @sBady_a
set @Bady_b = @Bady_b - @sBady_b
set @Type_a = @Type_a - @sType_a
set @Type_b = @Type_b - @sType_b
set @Wing = @Wing - @sWing
insert into @Temp
select @i , @sBady_a , @sBady_b , @sType_a , @sType_b , @sWing , @job_qty
end
RETURN
END
-
다초
2013.06.25 13:24
답변감사합니다. 한번의 쿼리로만 해결하려고 해서 방법이 떠오르질 않았던거 같습니다.
어느정도 감이 잡히는거 같습니다.
-
건우아빠
2013.06.25 13:30
수정중이 였는데 ..... 잘하면 한방쿼리도 나올듯 합니다.. 좀 복잡하기는 하네요...
Q/A 댓글로 방배정이나 분배로 조회해 보시면 응용할 만한게 있지 않을까 봅니다.
-
다초
2013.06.25 14:53
네 감사합니다. 지금 열심히 응용하고 있습니다.^^
-
다초
2013.06.25 17:11
마이너스 수량이나 마이너스 + 플러스수량이 들어갈때는 문제가 되네요
쉽지가 않네요 ㅜㅜ
-
건우아빠
2013.06.25 17:29
어떤 내용인지는 모르겠지만
실제 마이너스가 들어가는 경우가 어떤 상황인지가 ?
재고상 마이너스라면 0으로 보는게 맞을듯 하고...
작업상 해체라면 약간은 다를듯 하지만..
실제 내용이 뭐냐에 따라 달라질듯 하네요.
-
다초
2013.06.25 17:42
출고될때인데요 판매될경우(+), 반품할경우(-), 판매와 반품이 동시에 일어날경우입니다
-
건우아빠
2013.06.25 17:48
반품인 경우 와 판매인 경우라면 구분을 가지고
반품일때는 배분하는 루틴이 아니 재고에 + 하는 방향으로 하시는게 좋을듯 합니다.
반품이 경우에는 굳이 분배할 필요가 없지 않나요...
010-2696-7926 지면상이라 설명하기가 힘드네요... ㅎㅎ
동시에 일어나는 경우가 창고에 반품이 들어오면서 판매가 되는지 ?
주문상 반품과 판매가 이루어지는지에 따라 달라질 것 같구요..
단순 주문상 판매에 대한 반품인지에 따라서도 처리 방식이 달라질수도 있을듯 합니다.
동시에 실물의 이동으로 본다면 반품을 우선으로 하고 판매를 처리하는 순서로 하는게 맞을수도 있습니다.
전화 주세요...
-
다초
2013.06.25 18:07
이렇게까지 확인해주셔서 감사합니다. 연락드리겠습니다.
-
맨즈밤
2013.06.25 18:50
끄적이다가 퇴근시간이 되어서.....날개수량 계산부분이 덜 되었는데, 일단 하던거까지 올려보겠습니다.
귀차니즘이 발생해서 임시테이블이 좀 만들어졌군요... 2012는 앞행 뒤행 처리를 위한 분석함수가 있어서 좀더 활용폭이 넓은데,
그 이전버전은 그런게없어서리....
우선 함수를 하나 만들고,,
ALTER FUNCTION F_TEST
(
@A1 INT,
@A2 INT,
@A3 INT,
@A4 INT,
@A5 INT,
@A1_FLAG INT,
@A2_FLAG INT,
@A3_FLAG INT,
@A4_FLAG INT,
@A5_FLAG INT
)
RETURNS INT
AS
BEGIN
DECLARE @RETURN_VAL INT
SELECT @RETURN_VAL=ISNULL(MIN(F),0)
FROM (
SELECT F=CASE WHEN @A1_FLAG=1 THEN @A1 ELSE 999 END
UNION ALL
SELECT CASE WHEN @A2_FLAG=1 THEN @A2 ELSE 999 END
UNION ALL
SELECT CASE WHEN @A3_FLAG=1 THEN @A3 ELSE 999 END
UNION ALL
SELECT CASE WHEN @A4_FLAG=1 THEN @A4 ELSE 999 END
UNION ALL
SELECT CASE WHEN @A5_FLAG=1 THEN @A5 ELSE 999 END
) A
--WHERE F<>0
RETURN @RETURN_VAL
END그리고 다음 쿼리
DROP TABLE #TEMP
DROP TABLE #TEMP1
DROP TABLE #TEMP3CREATE TABLE #TEMP
( 키값 CHAR(3),
몸체A품번 Int, 몸체A품명 varchar(10), 몸체A수량 int,
몸체B품번 Int, 몸체B품명 varchar(10), 몸체B수량 int,
A타입품번 Int, A타입품명 varchar(10), A타입수량 int,
B타입품번 Int, B타입품명 varchar(10), B타입수량 int,
날개품번 Int, 날개품명 varchar(10), 날개수량 int
)CREATE TABLE #TEMP1
(
SEQ INT IDENTITY(1,1),
몸체A Int,
몸체B Int,
A타입 Int,
B타입 Int,
날개 Int
)
Insert Into #TEMP Values ('001',1,'몸체A',10, 2,'몸체B',3, 3,'A타입',5, 4,'B타입',12, 5,'날개',43);
Insert Into #TEMP Values ('002',1,'몸체A',20, 2,'몸체B',10, 3,'A타입',10, 4,'B타입',5, 5,'날개',12);
Insert Into #TEMP Values ('003',1,'몸체A',20, 2,'몸체B',18, 3,'A타입',5, 4,'B타입',10, 5,'날개',50);
Insert Into #TEMP1 Values(1,0,1,0,1)
Insert Into #TEMP1 Values(0,1,1,0,1)
Insert Into #TEMP1 Values(1,0,0,1,1)
Insert Into #TEMP1 Values(0,1,0,1,1)Insert Into #TEMP1 Values(1,0,1,0,0)
Insert Into #TEMP1 Values(0,1,1,0,0)
Insert Into #TEMP1 Values(1,0,0,1,0)
Insert Into #TEMP1 Values(0,1,0,1,0)Insert Into #TEMP1 Values(1,0,0,0,0)
Insert Into #TEMP1 Values(0,1,0,0,0)Insert Into #TEMP1 Values(0,0,1,0,0)
Insert Into #TEMP1 Values(0,0,0,1,0)
Insert Into #TEMP1 Values(0,0,0,0,1)
Select T2.SEQ
,키값
,T1.몸체A수량
,T1.몸체B수량
,A타입수량
,B타입수량
,날개수량
,몸체A_FLAG=T2.몸체A
,몸체B_FLAG=T2.몸체B
,A타입수량_FLAG=T2.A타입
,B타입수량_FLAG=T2.B타입
,날개수량_FLAG=T2.날개
INTO #TEMP3
From #TEMP T1 CROSS JOIN #TEMP1 T2
ORDER BY T2.SEQ
goWITH TEST_T (SEQ,키값,몸체A수량,몸체B수량,A타입수량,B타입수량,날개수량,최소값
,몸체A_FLAG,몸체B_FLAG,A타입수량_FLAG,B타입수량_FLAG,날개수량_FLAG )
AS (
SELECT SEQ,키값,몸체A수량,몸체B수량,A타입수량,B타입수량,날개수량,
최소값=DBO.F_TEST(몸체A수량 ,몸체B수량,A타입수량,B타입수량,날개수량,
몸체A_FLAG,
몸체B_FLAG,
A타입수량_FLAG,
B타입수량_FLAG,
날개수량_FLAG)
,몸체A_FLAG,몸체B_FLAG,A타입수량_FLAG,B타입수량_FLAG,날개수량_FLAG
FROM #TEMP3
WHERE SEQ=1
UNION ALL
SELECT T1.SEQ,T1.키값,
CASE WHEN T2.몸체A_FLAG=1 THEN T2.몸체A수량-T2.최소값 ELSE T2.몸체A수량 END,
CASE WHEN T2.몸체B_FLAG=1 THEN T2.몸체B수량-T2.최소값 ELSE T2.몸체B수량 END,
CASE WHEN T2.A타입수량_FLAG=1 THEN T2.A타입수량-T2.최소값 ELSE T2.A타입수량 END,
CASE WHEN T2.B타입수량_FLAG=1 THEN T2.B타입수량-T2.최소값 ELSE T2.B타입수량 END,
CASE WHEN T2.날개수량_FLAG=1 THEN T2.날개수량-T2.최소값*2 ELSE T2.날개수량 END,
최소값=DBO.F_TEST( CASE WHEN T2.몸체A_FLAG=1 THEN T2.몸체A수량-T2.최소값 ELSE T2.몸체A수량 END ,
CASE WHEN T2.몸체B_FLAG=1 THEN T2.몸체B수량-T2.최소값 ELSE T2.몸체B수량 END ,
CASE WHEN T2.A타입수량_FLAG=1 THEN T2.A타입수량-T2.최소값 ELSE T2.A타입수량 END,
CASE WHEN T2.B타입수량_FLAG=1 THEN T2.B타입수량-T2.최소값 ELSE T2.B타입수량 END,
CASE WHEN T2.날개수량_FLAG=1 THEN T2.날개수량-T2.최소값*2 ELSE T2.날개수량 END,
T1.몸체A_FLAG,
T1.몸체B_FLAG,
T1.A타입수량_FLAG,
T1.B타입수량_FLAG,
T1.날개수량_FLAG )
,T1.몸체A_FLAG,T1.몸체B_FLAG,T1.A타입수량_FLAG,T1.B타입수량_FLAG,T1.날개수량_FLAG
FROM #TEMP3 T1
INNER JOIN TEST_T T2
ON T1.키값=T2.키값 AND T1.SEQ=T2.SEQ+1
)
SELECT 키값,SEQ,몸체A_FLAG,몸체B수량,A타입수량,B타입수량,날개수량, 적용수량=최소값
FROM TEST_T
ORDER BY 키값,SEQ -
다초
2013.06.26 09:00
맨즈밤님 답변 감사합니다. 이방법도 활용해보겠습니다.
2012는 앞행 뒤행 처리를 위한 분석함수도 뭔지 확인해보겠습니다.
-
다초
2013.06.26 09:03
건우아빠님 시간내서 이것저것 말씀해주셔서 감사했습니다.
업무에 대한 분석이 조금 부족했던거 같습니다.
말씀해주셨던부분 확인하면 잘처리될거 같습니다.
제가 너무 쿼리에만 집중했던거 같습니다.
많은도움 되었습니다.
이해가 어려워서 엑셀화 아래 내용이 맞는거죠..... 자 고수님들 힘한번 써주세요.....
저라면 쿼리보다는 프로시저에서 커서로 돌리는겠습니다.
쿼리는 투자대비 별로 ?