【问题标题】:How to group data by summed amount less than x如何按总和小于 x 对数据进行分组
【发布时间】:2021-04-25 09:00:06
【问题描述】:

在 sql 中处理此问题时遇到问题。有一张与客户相关的支票金额表。如果我想给他们每个支付的唯一号码,我无法弄清楚如何仅使用更新语句而不是逐行进行(有大量数据)

我必须按特定标准进行分组,然后发出付款,但不能超过 10000 美元。

表格

customer CheckAmount
a   4000
a 5000
a 2001
b 3333
c 8000
d 11000

我更新后应该是这样的:

customer checkamount paymentnumber
a 4000 1
a 5000 1
a 2001 2
b 3333 3
c 8000 4
d 11000 5

这是否可能仅在更新语句中?

【问题讨论】:

  • 您的数据库是否使用 MySQL、SQL Server、Oracle、PostgreSQL 或其他东西?您的数据是否按客户分类?不应该为 9001 而不是 2001 编写检查 #2 吗?为什么客户d 在限额为 10K 时收到 11K 的支票?
  • SQL 服务器。编辑了一个错字,都应该是 2001, .限制是 10K,但如果超出单个订单项,我对此无能为力,不能拆分。数据只是具有多个客户的行项目发票,例如,我提取了其中一个主表中的两列,以使其易于显示。谢谢。
  • 可以使用逐行操作来做到这一点。不确定基于集合的解决方案。我会考虑为客户和付款生成两个额外的 int 列,然后使用嵌套的 while 循环来遍历这些检查和更新付款编号。显然效率不高,但可行。或者,您可以尝试在单个 while 循环中进行自联接
  • 是否可以在源数据中多获取一列,以按时间或按付款的序数确定记录顺序?
  • 数据来自大约 20 个加入的表。我只包括了那几列,以便更容易查看是否有人可以直接告诉我是否可以完成。目前有id。我知道它可以通过循环来完成,我只是不确定使用 floor 或其他东西是否可以实现这一点。多年来一直在做 sql,但我还没有看到任何类似的东西,我很难过。根据行数等很容易做到,但我只是不知道分组

标签: sql database querying


【解决方案1】:

如果有另外一个按时间标识交易的列就可以解决这个问题,像这样:

transaction_num     customer    checkamount
1                   a           4000    
2                   a           5000    
3                   a           2001    
4                   b           3333    
5                   c           8000    
6                   d           11000

那么更新语句可能是这样的:

UPDATE p 
SET p.paymentnumber = agg.new_paymentnumber
FROM payments p
JOIN (
  SELECT *,
    DENSE_RANK() OVER (
      ORDER BY customer,
      -- Only the first payments are not higher than 10,000:
      /* CASE WHEN agg_sum <= 10000 THEN 0 ELSE agg_sum END */
      -- All payments are within 10,000:
      CEILING(agg_sum / 10000)
    ) AS new_paymentnumber
  FROM (
    SELECT *, SUM(checkamount) OVER (
      PARTITION BY customer ORDER BY transaction_num
    ) AS agg_sum
    FROM payments
  ) t 
) agg ON p.transaction_num = agg.transaction_num

fiddle

【讨论】:

  • 这是一个非常优雅的解决方案,使用 dense_rank 和 case in order by 子句。
  • 我真的很喜欢,谢谢,但它似乎在第一组之后就坏了。我给出的数据示例除了第一组之外没有任何多条记录。当我尝试处理我的数据时,它只对第一个进行分组,然后它会添加 0,所以我调整了你放在小提琴上的代码,并将它们单独拆分。感谢您的帮助,我会在早上尝试更多,看看我是否可以调整您发送到工作的内容。
  • 创建表支付 (transaction_num int, customer varchar(20), checkamount int, paymentnumber int);插入付款(transaction_num,客户,支票金额)选择 1,'a',4000 union all select 2,'a',5000 union all select 3,'a',2001 union all select 4,'b',3333 union all select 5, 'c', 8000 union all select 6, 'd', 11000 union all select 7,'e', 500 union all select 8,'e', 500 union all select 9,'e', 500 union all选择 10 ,'e', 500;
  • 没有任何集合的分组。你写道:I have to group by a certain criteria。这个标准究竟是什么?请在您的问题中提供解决问题实际需要的示例数据集和所需的输出。
  • 这是一个按客户分组交易的示例:fiddle
猜你喜欢
  • 1970-01-01
  • 2013-02-13
  • 2021-05-06
  • 2020-05-15
  • 2020-07-14
  • 1970-01-01
  • 2020-03-22
  • 2016-02-02
  • 2021-12-05
相关资源
最近更新 更多