在OVER中使用CTE(PARTITION BY)

时间:2017-03-22 14:06:33

标签: sql sql-server common-table-expression window-functions

我正在尝试从表中的3列计算卷,并仅返回唯一卷。我们有许多行具有相同的WidthHeightLength,因此我的卷计算自然会有Volume的重复返回值。我的印象是,为了实现这一点,我必须使用OVERPARTITIONCTE,因为不允许在OVER中引用别名

WITH
cteVolume (Id, Volume)
AS 
(
    SELECT Id, Width * Height * [Length] AS Volume FROM  PackageMaterialDimensions
)
SELECT * 
INTO #volumeTempTable
FROM (
SELECT pp.ID, (pp.Width * pp.Height * pp.[Length]) AS Volume,
ROW_NUMBER() OVER(PARTITION BY cte.Volume ORDER BY pp.ID DESC) rn
FROM PlanPricing pp
INNER JOIN cteVolume cte ON pp.ID = cte.Id
) a
WHERE rn = 1

SELECT * FROM #volumeTempTable
ORDER BY Volume DESC

DROP TABLE #volumeTempTable  

注意,临时表的原因是因为我打算对这些数据做一些额外的工作。我目前正在调试,所以我使用这些表输出到数据窗口

以下是此查询的错误
- 它仍然返回重复项 - 每行只返回一个卷 - 当表中有71000行时,它只返回约75行

如何修改此查询以基本执行以下操作
- 计算表格中每一行的体积
- 选择具有唯一体积计算的行。 (我不想在结果集中看到相同的音量两次)

编辑 - 按要求提供数据

当前数据集忽略额外的列
enter image description here

我想要的是
ID |卷
193 | 280个
286 | 350个
274 | 550个
241 | 720

基本上,我想计算每一行的体积,然后我想以某种方式按体积分组以减少重复并从每组中选择第一行

3 个答案:

答案 0 :(得分:1)

这样做你想要的吗?

WITH cteVolume (Id, Volume) AS (
      SELECT Id, Width * Height * [Length] AS Volume
      FROM PackageMaterialDimensions
    )
SELECT DISTINCT volume
FROM CTE ;

如果您想要每卷一个ID:

WITH cteVolume (Id, Volume) AS (
      SELECT Id, Width * Height * [Length] AS Volume
      FROM PackageMaterialDimensions
    )
SELECT volume, MIN(Id) as Id
FROM CTE
GROUP BY volume;

答案 1 :(得分:0)

也许您的问题来自于cte.volume表中PackageMaterialDimensions的分区,但您还要从pp.volume表中选择PlanPricing

如果没有关于数据集和表格的更多信息,则无法确认。

答案 2 :(得分:0)

据我所知,你不能在CTE的递归部分内使用windows函数。您必须在CTE部件内手动对它们求和。 所以,而不是

ROW_NUMBER() OVER(PARTITION BY cte.Volume ORDER BY pp.ID DESC) rn

只需写下

1 as rn

在第一部分,

rn+1 as rn

在第二部分。