sql - 时态表以一种奇怪的模式检索具有不同顺序的分区行集
问题描述
我正在解决一项基于 Adventure Works 2012 的任务。
对于每个财政年度(2007 年和 2008 年),找出累计运行收入总额达到 1000 万美元的第一个日期。
输出应包括以下列:
- 财政年度(2007 年或 2008 年)。
- 达到或超过 1000 万美元的订单日期。
- 财政年度内达到或超过 1000 万美元的订单计数(例如,如果在第 50 个订单上达到 1000 万美元的目标,则报告的适当值为 50)。
- 达到 1000 万美元目标的订单 ID。
- 运行总收入达到或超过 1000 万美元。
DROP TABLE #data
SELECT YEAR(DATEADD(MONTH, 6, OrderDate)) FiscalYear, CAST(OrderDate AS DATE) OrderDate, SalesOrderID OrderID,
COUNT(*) OVER(Partition BY YEAR(DATEADD(MONTH, 6, OrderDate)) ORDER BY SalesOrderID) OrderCount,
SUM(SubTotal) OVER(Partition BY YEAR(DATEADD(MONTH, 6, OrderDate)) ORDER BY SalesOrderID) RunTotal
INTO #data
FROM sales.SalesOrderHeader
WHERE YEAR(DATEADD(MONTH, 6, OrderDate)) IN (2007, 2008)
SELECT TOP 1 FiscalYear, OrderDate, OrderCount, OrderID, RunTotal
FROM #data
WHERE RunTotal>=10000000 AND FiscalYear=2007
UNION
SELECT TOP 1 FiscalYear, OrderDate, OrderCount, OrderID, RunTotal
FROM #data
WHERE RunTotal>=10000000 AND FiscalYear=2008
时态表 #data 检索按 FiscalYear 分区的正确集合,并按 OrderID 在分区内排序 3 次连续执行,并在以下 UNION 查询中呈现正确结果 在 此处输入图像描述
但是,在接下来的 2 次执行中,顺序被打乱了:数千个 2008 财年行推高了记录集,而忽略了 COUNT 顺序,并且 2008 年(TOP 1)的结果变得不正确 ,请在此处输入图像描述
然后它恢复正常执行 3 次,依此类推。每当我抹去
SUM(SubTotal) OVER(Partition BY YEAR(DATEADD(MONTH, 6, OrderDate)) ORDER BY SalesOrderID) RunTotal
从临时表中,订单工作正常。我对这种奇怪的行为感到困惑。
解决方案
没有 .该TOP
子句毫无意义ORDER BY
。在您的查询中,您是说“从 FiscalYear xxxx 和 RunTotal >= 10000000 的所有结果行中任意选择一行”。这样做的原因是表数据被认为是一组无序的数据。没有ORDER BY
就没有保证的顺序。
因此:
SELECT * FROM
(
SELECT TOP 1 FiscalYear, OrderDate, OrderCount, OrderID, RunTotal
FROM #data
WHERE RunTotal >= 10000000 AND FiscalYear = 2007
ORDER BY RunTotal
) year2007
UNION ALL
SELECT * FROM
(
SELECT TOP 1 FiscalYear, OrderDate, OrderCount, OrderID, RunTotal
FROM #data
WHERE RunTotal >= 10000000 AND FiscalYear = 2008
ORDER BY RunTotal
) year2008;
我已更改UNION
为UNION ALL
,因为没有要删除的重复项。
查询结果又是一张表。所以,同样的规则适用:如果你想要一些特定的订单,你需要ORDER BY
. 如果您想要 2008 年之前的 2007 年,请添加ORDER BY FiscalYear
到查询的末尾。
推荐阅读
- javascript - jQuery获取动态嵌套元素调用animate方法
- javascript - 我可以在闭包中获取变量的更新值吗?
- python - 在 Python 中打印时如何在其他两个字符串之间插入一个字符串
- python - Django将子字符串包含在带有href属性的锚标记的字符串中
- scala - 批量查询datastax图顶点,共50个顶点
- c - 在C中将两个二维数组合并为一个一维数组
- kotlin - 如何在 kotlin 中获得价值?
- java - 在第一个位置插入元素时返回不正确的链接列表
- mysql - 更新缺失行的数据库的最佳方法
- javascript - 反应过渡组过渡动画无法退出