我有一张看起来像这样的表:
+------+------+------------------+
| item | val | timestamp |
+------+------+------------------+
| 1 | 3.66 | 16-05-2011 09:17 |
| 1 | 2.56 | 16-05-2011 09:47 |
| 2 | 4.23 | 16-05-2011 09:37 |
| 3 | 6.89 | 16-05-2011 11:26 |
| 3 | 1.12 | 16-05-2011 12:11 |
| 3 | 4.56 | 16-05-2011 13:23 |
| 4 | 1.10 | 16-05-2011 14:11 |
| 4 | 9.79 | 16-05-2011 14:23 |
| 5 | 1.58 | 16-05-2011 15:27 |
| 5 | 0.80 | 16-05-2011 15:29 |
| 6 | 3.80 | 16-05-2011 15:29 |
+------+------+------------------+
所以,当天所有项目的总计: 2011年5月16日是: 40.09
现在我想检索此列表中的哪些项目占总数的80%。 让我举个例子:
从总金额百分比权重的项目开始,我想要检索构成总计80%的项目的分组列表:
+------+------+
| item | val |
+------+------+
| 3 | 12.57|
| 4 | 10.89|
| 1 | 6.22|
+------+------+
正如您所看到的,结果集中的元素是按项目代码分组的元素,并从元素中排序,在总计下降百分比中具有更大的权重,直到达到80%阈值。
从第2项开始,项目将从结果集中丢弃,因为它们超过了80%的阈值,因为:
12.57 + 10.89 + 6.22 + 4.23 > 32.07 (80 % of the grand total )
这不是作业,这是一个真实的背景,我被绊倒,我需要通过一个查询来实现结果......
查询应该在MySQL,SQL Server,PostgreSQL上进行未修改或几乎没有更改。
答案 0 :(得分:4)
您可以使用单个查询执行此操作:
WITH Total_Sum(overallTotal) as (SELECT SUM(val)
FROM dataTable),
Summed_Items(id, total) as (SELECT id, SUM(val)
FROM dataTable
GROUP BY id),
Ordered_Sums(id, total, ord) as (SELECT id, total,
ROW_NUMBER() OVER(ORDER BY total DESC)
FROM Summed_Items),
Percent_List(id, itemTotal, ord, overallTotal) as (
SELECT id, total, ord, total
FROM Ordered_Sums
WHERE ord = 1
UNION ALL
SELECT b.id, b.total, b.ord, b.total + a.overallTotal
FROM Percent_List as a
JOIN Ordered_Sums as b
ON b.ord = a.ord + 1
JOIN Total_Sum as c
ON (c.overallTotal * .8) > (a.overallTotal + b.total))
SELECT id, itemTotal
FROM Percent_List
将产生以下结果:
id itemTotal
3 12.57
4 10.89
1 6.22
请注意,这将不在mySQL(无CTE)中工作,并且需要更新版本的postgreSQL才能工作(否则不支持OLAP功能)。 SQLServer应该能够按原样运行语句(我认为 - 这是在DB2上编写和测试的)。否则,您可以尝试将其转换为相关的表连接等,但如果它甚至可能(不那么<存储过程或重新组装更高级别的语言可能是您唯一的选择。)
答案 1 :(得分:0)
我不知道用单个查询可以做到这一点;你可能需要创建一个存储过程。 proc的步骤是这样的:
SUM
val DESC