2010-05-29 3 views
1

다음과 같이 SQL 시나리오를 개선하려고합니다.SQL 사용자에게 ID를 할당하는 시나리오

상품에 대한 상점에 ​​대해 반품 된 상품의 ID가있는 '반품'테이블이 있습니다. 그 구조는 다음과 같습니다.

Returns 
------------------------- 
Return ID | Shop | Item 
------------------------- 
    1   Shop1 Item1 
    2   Shop1 Item1 
    3   Shop1 Item1 
    4   Shop1 Item1 
    5   Shop1 Item1 

아래 그림과 같이 하나 이상의 테이블 공급 업체, 공급 업체 및 품목이 있습니다.

Supplier 
--------------------------------- 
Supplier | Shop | Item | Volume 
--------------------------------- 
    supp1 Shop1 Item1 20% 
    supp2 Shop1 Item1 80% 

이제 보셨 듯이 supp1은 총 item1 볼륨의 20 %를 공급하고 supp2는 item1의 80 %를 shop1에 제공하고 있습니다. 그리고 동일한 Shop1에 대해 동일한 Item1에 대해 5 개의 항목 반환이있었습니다. 이제 Supp1에 네 개의 리턴 ID를 할당하고 나머지 하나는 supp2에 리턴 ID를 할당해야합니다. 이 숫자 할당은 공급 업체의 공급량 비율에 따라 결정됩니다. 이 배분은 공급 된 품목의 비율에 따라 다릅니다.

이제 임시 테이블을 사용하여 아래 표시된 것처럼 RANK를 사용하는 방법을 시도했습니다.

임시 테이블 1에는 Shop, Return Id, Item, 반환 ID의 총 개수 및 반환 ID의 순위가 있습니다.

임시 테이블 2에는 매장, 공급 업체, 품목 및 비율과 비율이 표시됩니다.

이제 위에서 설명한 것처럼 최상위 반환 ID를 최고 공급 업체에 할당하는 데 어려움을 겪고 있습니다. SQL은 루프를 가지고 있지 않으므로 어떻게 이럴 수 있습니까? 나는 이것을하는 여러 가지 방법을 묶어왔다.

내 환경은 Teradata (ANSI SQL이면 충분)입니다.

답변

1

업데이트 : 루프해야합니다. 여기서 시작점으로 사용할 수있는 몇 가지 SQL 코드가 있습니다. 기본적으로 임시 탭과 ROW_NUMBER()를 사용합니다.

-- gather suppliers in temp table 
DECLARE @SupplierTemp table 
     ( [RowId] int 
      ,[Supplier] nvarchar (50) 
      ,[ReturnCount] int) 

-- gather supplier with return count 
INSERT INTO @SupplierTemp 
    SELECT ROW_NUMBER() OVER(ORDER BY [Supplier].[Supplier] DESC, [Supplier].[Supplier]) 
     ,[Supplier].[Supplier] 
     , COUNT([Supplier].[Supplier])*[Supplier].[Volume]/100 AS ReturnCount 
    FROM [Supplier] 
    INNER JOIN [Returns] ON (([Returns].[Item] = [Supplier].[Item]) 
         AND ([Returns].[Shop] = [Supplier].[Shop])) 
    GROUP BY [Supplier].[Supplier], [Supplier].[Volume] 
    ORDER BY [Supplier].[Supplier] 

-- gather returns in temp table 
DECLARE @ReturnsTemp table 
     ( [RowId] int 
     ,[Id] int) 

-- gather returns 
INSERT INTO @ReturnsTemp 
    SELECT ROW_NUMBER() OVER(ORDER BY [Returns].[Id] DESC, [Returns].[Id]) 
     ,[Returns].[Id] 
    FROM [Returns] 

-- gather results in temp table 
DECLARE @ResultsTemp table 
     ( [Supplier] nvarchar(50) 
     ,[Id] int) 

DECLARE @rrowid as int 
DECLARE @rid as int 

-- loop over all suppliers 
-- loop once for each [ReturnCount] 
-- find the next avialable Id 
DECLARE @srowid as int 
DECLARE @loopCnt as int 
DECLARE @supplier as nvarchar(50) 

-- get first supplier 
SELECT @srowid = (SELECT MIN([RowId]) FROM @SupplierTemp) 
SELECT @loopCnt = [ReturnCount] FROM @SupplierTemp WHERE [RowId] = @srowid 
SELECT @supplier = [Supplier] FROM @SupplierTemp WHERE [RowId] = @srowid 

-- loop over suppliers 
WHILE @srowid IS NOT NULL 
    BEGIN 
    -- loop of number of returns  
    WHILE @loopCnt > 0 
     BEGIN 
     -- find the Id to return 
     SELECT @rrowid = (SELECT MIN([RowId]) FROM @ReturnsTemp) 
     SELECT @rid = [Id] FROM @ReturnsTemp WHERE [RowId] = @rrowid 

     INSERT INTO @ResultsTemp VALUES (@supplier, @rid) 

     DELETE FROM @ReturnsTemp WHERE [RowId] = @rrowid 

     SELECT @loopCnt = @loopCnt - 1 
     END 

    -- delete current item from table to keep loop moving forward...  
    DELETE FROM @SupplierTemp WHERE [RowId] = @srowid 

    -- get next supplier. 
    SELECT @srowid = (SELECT MIN([RowId]) FROM @SupplierTemp) 
    SELECT @loopCnt = [ReturnCount] FROM @SupplierTemp WHERE [RowId] = @srowid 
    SELECT @supplier = [Supplier] FROM @SupplierTemp WHERE [RowId] = @srowid 
    END 

SELECT * FROM @ResultsTemp 
+0

내 첫 번째 대답과 질문을 읽어보고 싶어요 : 내 샘플에 대한 나는 다음과 같은 시도 SQL 서버를 2008 년

을 사용했다. – Zamboni

+0

고맙습니다. 나는 그것을 조사하고 당신을 업데이트 할 것입니다. 다시 한 번 감사드립니다. –

관련 문제