SQL为用户分配id的场景

发布于 2024-09-03 02:50:47 字数 980 浏览 6 评论 0原文

我有一个如下的sql场景,我一直在努力改进。

有一个“退货”表,其中包含针对商店的商品退货的 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 向 shop1 供应 item1 总量的 20%,supp2 向 shop1 供应 Item1 的 80%。同一 Shop1 的同一 Item1 有 5 次退货。 现在我需要将任意四个返回 ID 分配给 Supp1,并将剩余一个返回 ID 分配给 supp2。这种数量的分配是基于供应商的供应量百分比的比率。这种分配根据供应物品的数量比例而变化。

现在我尝试了一种使用临时表来使用 RANK 的方法,如下所示。

临时表 1 将包含商店、退货 ID、商品、退货 ID 总数和退货 ID 排名。

临时表2将有商店、供应商、项目及其比例和比例等级。

现在,我面临着将顶级退货 ID 分配给顶级供应商的困难,如上所示。由于 SQL 没有循环,我怎样才能实现这一点。我已经结合了几种方法来做到这一点。

我的环境是Teradata(ANSI SQL就足够了)。

I have an sql scenario as follows which I have been trying to improve.

There is a table 'Returns' which is having ids of the returned goods against a shop for an item. Its structure is as below.

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

There is one more table Supplier with Shop, supplier and Item as shown below.

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

Now as you see supp1 is supplying 20 % of total item1 volume and supp2 is supplying 80% of Item1 to shop1. And there were 5 return of items against the same Item1 for same Shop1.
Now I need to allocate any four return IDs to Supp1 and remaining one return Id to supp2. This allocation of numbers is based on the ratio of the supplied volume percentage of the supplier. This allocation varies depending on the ratio of volume of supplied items.

Now I have tried a method of using RANKs as shown below by use of temp tables.

temp table 1 will have Shop, Return Id, Item, Total count of return IDs and Rank of the return id.

temp table 2 will have shop, Supplier, Item and his proportion and rank of proportion.

Now I am facing the difficulty in allocating top return ids to top supplier as illustrated above. As SQL doesnt have loops how can I achieve this. I have been tying several ways of doing this.

My environment is Teradata (ANSI SQL is enough).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

像极了他 2024-09-10 02:50:47

更新:
您需要循环,这里有一些 SQL 代码,您可以将其用作起点。
基本上我使用临时 tabes 和 ROW_NUMBER()。
对于我的示例,我使用 SQL SERVER 2008。

请尝试以下操作:

-- 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

UPDATE:
You need to loop, here is some SQL code you can use as a starting point.
Basically I use temporary tabes and ROW_NUMBER().
For my sample I used SQL SERVER 2008.

Try the following:

-- 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文