根据总计检索组的详细行

发布于 2024-12-14 08:34:17 字数 1297 浏览 0 评论 0原文

我有一张看起来像这样的表格:

+------+------+------------------+
| 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%。 让我举个例子:

  • 总计:40.09
  • 总计的 80%:32.07

从我想要检索分组的总金额中具有更多百分比权重的项目开始占总计 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 上运行,无需修改或只需少量更改。

I have a table that looks like this one :

+------+------+------------------+
| 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 |
+------+------+------------------+

so, the grand total of all item for the day : 16 May 2011 is : 40.09

Now i want to retrieve which items of this list form an amount of 80% of the grand total.
Let me make an example :

  • Grand Total : 40.09
  • 80% of the Grand Total : 32.07

starting from the item with more percentage weight on the total amount i want to retrieve the grouped list of the item that form the 80% of the grand total :

+------+------+
| item | val  |
+------+------+
|  3   | 12.57|
|  4   | 10.89|
|  1   |  6.22|
+------+------+

As you can see the elements in the result set are the elements grouped by item code and ordered from the element with greater percentage weight on the grand total descending until reaching the 80% threshold.

From the item 2 onward the items are discarded from the result set because they exceed the threshold of 80%, because :

12.57 + 10.89 + 6.22 + 4.23 > 32.07 (80 % of the grand total )

This is not an homework, this is a real context where i am stumbled and i need to achieve the result with a single query ...

The query should run unmodified or with few changes on MySQL, SQL Server, PostgreSQL .

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

白云悠悠 2024-12-21 08:34:17

可以使用单个查询来完成此操作:

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 上编写和测试的)。否则,您可能尝试将其转换为相关表连接等,但即使可能(存储过程或在那么高级语言可能是您唯一的选择)。

You can do this with a single query:

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

Which will yield the following:

id      itemTotal
3       12.57  
4       10.89  
1       6.22  

Please note that this will not work in mySQL (no CTEs), and will require a more recent version of postgreSQL to work (otherwise OLAP functions are not supported). SQLServer should be able to run the statement as-is (I think - this was written and tested on DB2). Otherwise, you may attempt to translate this into correlated table joins, etc, but it will not be pretty, if it's even possible (a stored procedure or re-assembly in a higher level language may then be your only option).

北风几吹夏 2024-12-21 08:34:17

我不知道有什么方法可以通过单个查询来完成此操作;您可能必须创建一个存储过程。该过程的步骤如下所示:

  1. 使用 SUM 计算当天的总计
  2. 获取按 val DESC 排序的当天的各个记录
  3. 保持运行循环浏览各个记录时的总计;只要运行总计 < 0.8 * grandtotal,将当前记录添加到您的列表中

I don't know of any way this can be done with a single query; you'll probably have to create a stored procedure. The steps of the proc would be something like this:

  1. Calculate the grand total for that day by using a SUM
  2. Get the individual records for that day ordered by val DESC
  3. Keep a running total as you loop through the individual records; as long as the running total is < 0.8 * grandtotal, add the current record to your list
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文