在 OVER(PARTITION BY) 中使用 CTE
Posted
技术标签:
【中文标题】在 OVER(PARTITION BY) 中使用 CTE【英文标题】:Using a CTE in OVER(PARTITION BY) 【发布时间】:2017-03-22 14:06:32 【问题描述】:我正在尝试从表中的 3 列计算体积并仅返回唯一的体积。我们有许多行具有相同的Width
、Height
和Length
,因此我的体积计算自然会有Volume
的重复返回值。我的印象是,为了做到这一点,我必须使用OVER
、PARTITION
和CTE
,因为在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 行
我如何修改此查询以基本上执行以下操作 - 计算表中每一行的体积 - 选择具有独特体积计算的行。 (我不想在我的结果集中看到两次相同的卷)
编辑 - 按要求提供数据
当前数据集忽略多余的列
我想要的是 身份证 |音量 193 | 280 286 | 350 274 | 550 241 | 720
基本上,我想计算每一行的体积,然后我想以某种方式按体积分组,以减少重复并从每组中选择第一行
【问题讨论】:
请澄清“SELECT rows DISTINCT by volume”是什么意思。样本数据和期望的结果会有所帮助。 @AdrianSELECT MIN(id), Width * Height * [Length] AS Volume FROM PackageMaterialDimensions GROUP BY Width * Height * [Length]
不够吗?
【参考方案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;
【讨论】:
不,因为我在结果集中有重复的卷。我刚刚用您要求的信息更新了问题。让我知道该信息是否澄清了事情。 我可以在您建议的查询中执行DISTINCT
,但现在的问题是我需要更多的数据而不仅仅是卷。我至少需要 ID【参考方案2】:
也许您的问题来自于从PackageMaterialDimensions
表中分区cte.volume
,但您还从PlanPricing
表中选择pp.volume
?
如果没有关于您的数据集和表格的更多信息,无法确认。
【讨论】:
【参考方案3】:据我所知,您不能在 CTE 的递归部分中使用 windows 函数。您必须在 CTE 部分内手动对它们求和。 所以,而不是
ROW_NUMBER() OVER(PARTITION BY cte.Volume ORDER BY pp.ID DESC) rn
随便写
1 as rn
在第一部分,和
rn+1 as rn
在第二部分。
【讨论】:
以上是关于在 OVER(PARTITION BY) 中使用 CTE的主要内容,如果未能解决你的问题,请参考以下文章
在mysql中使用sum() over(Partition by)组合多行数据
使用 OVER (PARTITION BY ) 而不是 Group By
oracle查询中over(partition by ...order by ...)用法
Hive 问题 - Rank() OVER (PARTITION BY Dept ORDER BY sum(salary))
使用 Row_number() OVER(partition BY..) 以及声明局部变量
Junit 测试用例 - HSQLDB count(...) over (partition ... order by ...)