【问题标题】:SQL query to group based on sumSQL查询根据总和进行分组
【发布时间】:2014-11-04 01:53:27
【问题描述】:

我有一个简单的表,其中包含我想根据这些值的总和(不超过某个限制组总和)将其分块/分区为不同组的值。

例如,。想象一个像下面这样的表格:

Key   Value
-----------
A         1
B         4
C         2
D         2
E         5
F         1

我想分组,这样任何一个分组的总和都不会超过某个给定值(比如 5)。

结果会是这样的:

Group  Key    Value
-------------------
1      A          1     
       B          4
           --------  
           Total: 5     

2      C          2
       D          2
           --------
           Total: 4

3      E          5
           --------
           Total: 5

4      F          1
           --------
           Total: 1

这样的查询可能吗?

【问题讨论】:

  • @user545242 - 这是一个应该由报告引擎解决或输出到 Excel 并启用 Excel 的小计功能的问题。这不是您应该尝试在数据库中解决的问题类型。
  • @Thomas - 我不同意:不熟悉的问题(或问题集)并不意味着 sql 引擎不应该这样做。考虑到允许一些约束等,很有可能有一个解决方案。
  • @topchef - 我们同意不同意。这个问题完全是关于演示的。 SQL 语言面向集合的检索。我们可以使用查询来获取总计集。我们可以使用查询来获取单个金额的集合。试图像在 OP 中那样很好地显示小计就是为了报告。即使您可以生成一个返回这些结果的查询,数据层代码也会阻塞它。正确的答案是提取原始数据并使用报告工具。
  • 我认为我将不得不在脚本/报告工具中处理原始数据,但要求与演示无关(尽管我上面的格式很愚蠢)。我只需要按顺序对这些值进行分组——这与容量有关。我有一系列具有给定成本(价值)的作业和一系列容量有限的引擎/存储桶,需要如上所述将作业分散开。感谢迄今为止所有的 cmets。
  • @user545242 - 是否只是您想要输出中的小计但未按所示格式化?如果是这样,那可能是可能的。

标签: sql


【解决方案1】:

虽然我倾向于同意 cmets 最好在 SQL 之外完成这一点,但这里有一些 SQL 似乎大致可以满足您的要求:

with mytable AS (
    select 'A' AS [Key], 1 AS [Value] UNION ALL
    select 'B', 4 UNION ALL
    select 'C', 2 UNION ALL
    select 'D', 2 UNION ALL
    select 'E', 5 UNION ALL
    select 'F', 1
)
, Sums AS (
    select T1.[Key] AS T1K
        , T2.[Key] AS T2K
        , (SELECT SUM([Value])
           FROM mytable T3
           WHERE T3.[Key] <= T2.[Key]
           AND T3.[Key] >= T1.[Key]) AS TheSum
    from mytable T1
    inner join mytable T2
        on T2.[Key] >= T1.[Key]
)
select S1.T1K AS StartKey
    , S1.T2K AS EndKey
    , S1.TheSum
from Sums S1
left join Sums S2
    on (S1.T1K >= S2.T1K and S1.T2K <= S2.T2K)
    and S2.TheSum > S1.TheSum
    and S2.TheSum <= 5
where S1.TheSum <= 5
AND S2.T1K IS NULL

当我在 SQL Server 2008 上运行此代码时,我得到了以下结果:

StartKey    EndKey    Sum
A           B         5
C           D         4
E           E         5
F           F         1

从这些结果构建所需的组应该很简单。

【讨论】:

  • 谢谢!我会试试看。如果我想在一个组中显示完整的键集(假设我有一个超过两个的组)我想我可以尝试一些 BETWEEn 魔法。
【解决方案2】:

如果您希望每个集合中只有两个或更少的成员,您可以使用以下查询:

Select
  A.[Key] as K1 ,
  B.[Key] as K2 ,
  isnull(A.value,0) as V1 ,
  isnull(B.value,0) as V2 ,
  (A.value+B.value)as Total
from Table_1 as A left join Table_1 as B
on A.value+B.value<=5 and  A.[Key]<>B.[Key]

要查找具有更多成员的集合,您可以继续使用联接。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-12
    • 1970-01-01
    • 1970-01-01
    • 2012-10-07
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多