Oracle SQL Count 或 Sum 以防万一查询?
Posted
技术标签:
【中文标题】Oracle SQL Count 或 Sum 以防万一查询?【英文标题】:Oracle SQL Count or Sum in case query? 【发布时间】:2018-10-01 21:17:22 【问题描述】:我在 *** 上研究了五个不同的线程,我觉得我已经接近了,但仍然没有雪茄。我的原始表格有几个部分,每个部分有几行,每行有几个位置。我希望能够查询一个结果,该结果列出了部分、行、位置、有多少位置高于该行(位置编号较低)以及有多少位置低于该行(位置编号更大)。
这是我所拥有的:
SELECT section,
row,
position AS P,
SUM(case when position < P then 1 else 0 end) AS Above,
SUM(case when position > P then 1 else 0 end) AS Below
FROM OriginalTable
GROUP BY section, row, position
ORDER BY section, row, position
求和的情况没有将 P 识别为位置,当我将 P 更改为数字时,总和就差了。
【问题讨论】:
您能提供一些示例数据并期待结果吗? P 是在您的 SELECT 子句中定义的别名。您不能在同一个 SELECT 子句中的其他任何地方使用它(例如,在 SUM 或 COUNT 或其他任何内容中的条件中)。这与 COUNT 与 SUM 无关,也与对列别名的有效和无效引用有关。 【参考方案1】:一种可能的解决方案是相关子查询获取部分和行的较低/较高位置的count()
。
SELECT ot1.section,
ot1.row,
ot1.position,
(SELECT count(*)
FROM originaltable ot2
WHERE ot2.section = ot1.section
AND ot2.row = ot2.row
AND ot2.position > ot1.position) above,
(SELECT count(*)
FROM originaltable ot2
WHERE ot2.section = ot1.section
AND ot2.row = ot2.row
AND ot2.position < ot1.position) below
FROM originaltable ot1
ORDER BY ot1.section,
ot1.row,
ot1.position;
另一个正在使用count()
的窗口版本。
SELECT ot1.section,
ot1.row,
ot1.position,
count(*) OVER (PARTITION BY ot1.section,
ot1.row
ORDER BY ot1.position
RANGE BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING) - 1 above
count(*) OVER (PARTITION BY ot1.section,
ot1.row
ORDER BY ot1.position
RANGE BETWEEN UNBOUNDED PRECEDING
AND CURRENT ROW) - 1 below
FROM originaltable ot1
ORDER BY ot1.section,
ot1.row,
ot1.position;
【讨论】:
不使用CURRENT ROW
并减去1,你不能使用BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
和BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING
吗?
在第一个查询中,above
和 below
都有 <
。 --- 在第二个查询中,您颠倒了above
(位置号较小)和below
(位置号较大)的含义。
@Andreas:<
是正确的,更正了,谢谢。对于别名:我的意思是 above
是行“上方”的行数(如果在结果中可视化,则按降序排列)和 below
的模拟。至少这就是我获得OP的方式。不过也可能反过来……
哇,谢谢@stickybit!两种解决方案都有效,所以这是一个速度问题。上面的选项 1 需要 15.5 秒才能运行,选项 2 以惊人的 0.00 秒运行。【参考方案2】:
我只会使用row_number()
:
SELECT section, row, position AS P,
ROW_NUMBER() OVER (PARTITION BY section, row ORDER BY position ASC) - 1 as Above,
ROW_NUMBER() OVER (PARTITION BY section, row ORDER BY position DESC) - 1 as Below
FROM OriginalTable
ORDER BY section, row, position;
如果你有重复,那么问题就有点棘手了(尽管GROUP BY
会解决这个问题)。您可能需要DENSE_RANK()
而不是ROW_NUMBER()
。
【讨论】:
谢谢戈登。您的解决方案运行良好,速度很快(0.015 秒),但不如上面的@stickybit 解决方案#2 快。出色的工作和干净整洁的代码。 @ToddK 。 . .它们在性能上应该差不多。以毫秒为单位测量经过的时间需要非常小心 - 考虑到服务器负载、热缓存等因素。以上是关于Oracle SQL Count 或 Sum 以防万一查询?的主要内容,如果未能解决你的问题,请参考以下文章
oracle查询选择语句——count、sum、order by、group by