我有一个sql场景,如下所示,我一直在努力改进它。
有一个表'Returns‘,其中包含针对某商品的商店的退货is。它的结构如下。
Returns
-------------------------
Return ID | Shop | Item
-------------------------
1 Shop1 Item1
2 Shop1 Item1
3 Shop1 Item1
4 Shop1 Item1
5 Shop1 Item1还有一个包含Shop、Supplier和Item的表supplier,如下所示。
Supplier
---------------------------------
Supplier | Shop | Item | Volume
---------------------------------
supp1 Shop1 Item1 20%
supp2 Shop1 Item1 80%现在,如您所见,supp1提供了item1总量的20 %,supp2为shop1提供了80%的Item1。对于相同的Shop1,对于相同的Item1,有5个条目返回。现在,我需要将任意四个返回Id分配给Supp1,剩下的一个返回Id分配给supp2。此数量的分配是基于供应商的供货量百分比的比率。这种分配取决于所供应物品的体积比率。
现在,我尝试了一种通过使用临时表来使用排名的方法,如下所示。
临时表1将包含商店、退货Id、项目、退货id的总数和退货id的等级。
临时表2将有店铺、供应商、商品及其比例和比例排名。
现在,我面临着如上所述将顶级退货ids分配给顶级供应商的困难。由于SQL没有循环,我如何才能做到这一点。我一直在用几种方法来做这件事。
我的环境是Teradata (ANSI SQL就足够了)。
发布于 2010-05-29 22:25:05
更新:您需要进行循环,以下是一些SQL代码,您可以将其用作起点。基本上,我使用临时tabes和ROW_NUMBER()。在我的示例中,我使用了SQL server2008。
尝试以下操作:
-- 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 @ResultsTemphttps://stackoverflow.com/questions/2935275
复制相似问题