SQL 计算光标中每个产品的中位数
SQL Calculating Median per Product in Cursor
我正在尝试计算所选列表中每个产品 (SKU) 的中间值,但需要几个小时才能完成。我收到一个包含 4 列(SKU、Branch、PriceList、Campaign)的列表,我需要为每个 SKU 导入一个新数据行,并将 SKU 的中间值作为其 PriceList。
为了实现这一点,我将唯一的 SKU 列表导入到 TEMP TABLE,然后通过 TEMP TABLE 创建到 运行 的 CURSOR,计算 CURSOR 内的中值.
DECLARE @c BIGINT
DECLARE @SKUVal FLOAT
DECLARE @Total int
SELECT DISTINCT SKU,
'DFLT' AS Branch,
0 AS PriceList,
NULL AS Campaign
INTO #SKU
FROM eCommerce_Pricing
WHERE PriceList > 0.0
SELECT @Total = COUNT(*) FROM #SKU
DECLARE Cur1 CURSOR LOCAL SCROLL DYNAMIC READ_ONLY
FOR
SELECT SKU
FROM #SKU
OPEN Cur1
FETCH NEXT FROM Cur1 INTO
@SKU
WHILE @@FETCH_STATUS = 0
BEGIN
SET @c = (SELECT COUNT(*) FROM eCommerce_Pricing WHERE SKU = @SKU)
SELECT @SKUVal = AVG(1.0 * PriceList)
FROM (
SELECT PriceList FROM dbo.eCommerce_Pricing
WHERE SKU = @SKU
ORDER BY PriceList
OFFSET (@c - 1) / 2 ROWS
FETCH NEXT 1 + (1 - @c % 2) ROWS ONLY
) AS x
UPDATE #SKU
SET PriceList = @SKUVal
WHERE SKU = @SKU
SET @Total = @Total-1
PRINT CAST(@Total AS VARCHAR(100)) + ' records left'
FETCH NEXT FROM Cur1 INTO
@SKU
END
DEALLOCATE Cur1
SELECT * FROM #SKU
DROP TABLE #SKU
任何建议将不胜感激。
我正在使用 SQL 服务器 2014。
如果需要中位数,请使用 percentile_cont()
or percentile_disc()
。从你的问题我可以猜到,你想要这样的东西:
select distinct sku,
percentile_disc(0.5) within group (order by price) over (partition by sku) as median
from dbo.eCommerce_Pricing;
希望您已经了解到游标非常慢,并且不是解决 SQL 中几乎所有问题的最佳方法(好吧,它们确实有它们的用途,但不适用于数据库中已有的任何功能)。
我正在尝试计算所选列表中每个产品 (SKU) 的中间值,但需要几个小时才能完成。我收到一个包含 4 列(SKU、Branch、PriceList、Campaign)的列表,我需要为每个 SKU 导入一个新数据行,并将 SKU 的中间值作为其 PriceList。
为了实现这一点,我将唯一的 SKU 列表导入到 TEMP TABLE,然后通过 TEMP TABLE 创建到 运行 的 CURSOR,计算 CURSOR 内的中值.
DECLARE @c BIGINT
DECLARE @SKUVal FLOAT
DECLARE @Total int
SELECT DISTINCT SKU,
'DFLT' AS Branch,
0 AS PriceList,
NULL AS Campaign
INTO #SKU
FROM eCommerce_Pricing
WHERE PriceList > 0.0
SELECT @Total = COUNT(*) FROM #SKU
DECLARE Cur1 CURSOR LOCAL SCROLL DYNAMIC READ_ONLY
FOR
SELECT SKU
FROM #SKU
OPEN Cur1
FETCH NEXT FROM Cur1 INTO
@SKU
WHILE @@FETCH_STATUS = 0
BEGIN
SET @c = (SELECT COUNT(*) FROM eCommerce_Pricing WHERE SKU = @SKU)
SELECT @SKUVal = AVG(1.0 * PriceList)
FROM (
SELECT PriceList FROM dbo.eCommerce_Pricing
WHERE SKU = @SKU
ORDER BY PriceList
OFFSET (@c - 1) / 2 ROWS
FETCH NEXT 1 + (1 - @c % 2) ROWS ONLY
) AS x
UPDATE #SKU
SET PriceList = @SKUVal
WHERE SKU = @SKU
SET @Total = @Total-1
PRINT CAST(@Total AS VARCHAR(100)) + ' records left'
FETCH NEXT FROM Cur1 INTO
@SKU
END
DEALLOCATE Cur1
SELECT * FROM #SKU
DROP TABLE #SKU
任何建议将不胜感激。 我正在使用 SQL 服务器 2014。
如果需要中位数,请使用 percentile_cont()
or percentile_disc()
。从你的问题我可以猜到,你想要这样的东西:
select distinct sku,
percentile_disc(0.5) within group (order by price) over (partition by sku) as median
from dbo.eCommerce_Pricing;
希望您已经了解到游标非常慢,并且不是解决 SQL 中几乎所有问题的最佳方法(好吧,它们确实有它们的用途,但不适用于数据库中已有的任何功能)。