【问题标题】:Is there a way to calculate the correct average in SQL using the specified constraints?有没有办法使用指定的约束在 SQL 中计算正确的平均值?
【发布时间】:2019-07-10 12:19:22
【问题描述】:

我需要 SQL 来确定在上个月开立或关闭帐户的所有客户的正确平均值。这个计算是一个大得多的每月提取的一部分。此外,我需要输出不改变上个月未打开或关闭的所有预先存在的帐户的平均余额(通过案例陈述??不确定)。

目前,我们的系统通过对账户关闭或打开当天的平均余额进行快照来计算月末平均值。但这是不精确的,因为当一个帐户可能只开放一天或一个月内的 15 天(等)时,它会分配整月的“信用”。

基本数学告诉我,我需要计算平均值:

average_balance * days_open_in_month_closed/days_in_month (for closed accounts) 

average_balance * days_open_in_month_new/days_in_month (for new accounts) 

我在较大的查询中编写了 3 个子查询来获取所有日期/日期组件的数据;但是我遇到了我的 SQL 知识的界限。本质上,我不确定如何将所有内容组合在一起:我不知道如何插入平均计算,如何使所有内容都适合单个子查询(如果可以/应该)等等。

,(SELECT DAY(DATEADD(DD,-1,DATEADD(MM,DATEDIFF(MM,0,  GETDATE()), 0)))) AS days_in)month
,(SELECT DATEDIFF(DAY,DATEADD(month, DATEDIFF(month, -1, getdate()) -2, 0),closed_date) AS days_opened_in_month_closed
,(SELECT DATEDIFF(DAY,DATEADD(month, DATEDIFF(month, -1, getdate()) -2,0,),open_date) AS days_open_in_month_new

对于系统生成的平均余额为 1,800,000 美元、在 30 天的日历月中关闭 11 天的帐户,我预计 SQL 计算的平均值为 660,000 美元。

同样,对于一个系统生成的平均余额为 750,000 美元且在 30 天日历月结束前 2 天开设的帐户,我预计 SQL 计算的平均值为 45,000,000 美元。

我希望 SQL 不会改变系统生成的平均 500,000 的帐户,该帐户已打开整整 30 天的月份。

提前致谢。

【问题讨论】:

  • 你使用的是MySQL还是SQL Server
  • SQL 服务器。感谢您对标签的提醒 - mysql 被意外标记了。

标签: sql sql-server-2008


【解决方案1】:

让我们在这里讨论一些最佳实践:

首先,我建议您存储关闭日期/打开日期,就像您似乎存储它的方式一样,这意味着您将“days_in_month_closed”存储为参数。为了在将来节省一些转换时间,请确保您使用的是标准时间戳字符串(unixtime 整数应该可以解决问题)。

接下来,您将使用DATEDIFF()。如果您想查看从月初到客户关闭帐户日期之间的天数,您可以这样写

SELECT 
   DATEDIFF(day,
           `account_closed_date`
           CAST(CONCAT(YEAR(`account_closed_date),"-",MONTH(`account_closed_day`),"-01") AS date)  
FROM `accounts_table`

此查询将返回当月第一天与预期日期之间的整数天数。

如果你想找到下个月的月初,你会做类似的事情

SELECT 
   DATEDIFF(day,
           `account_open_date`
           DATEADD(MONTH, 1, CAST(CONCAT(YEAR(`account_open_date),"-",MONTH(`account_open_day`),"-01") AS date)))
FROM `accounts_table`

计算出这些数字后,您可以对余额表进行求和,并将其用作分母。

SELECT 
   (Select AVG(balance) From balances)/
   DATEDIFF(day,
           `account_open_date`
           DATEADD(MONTH, 1, CAST(CONCAT(YEAR(`account_open_date),"-",MONTH(`account_open_day`),"-01") AS date)))
FROM `accounts_table` at
Join balances b on at.account_id = b.account_id;

当然,这是假设您需要在此查询中计算每个帐户的平均余额。虽然更好的做法是分别计算这两个数字(即每个帐户一个作为Total Balance in the month,一个作为days account was active in the month,然后将它们分开。

对于新帐户,您想显示之前一个月的每一天的余额都是“零”,然后您只需除以一个月的总天数,您可以使用 @ 找到987654327@ 或使用函数Day(EOMONTH(date_you_needed)) 将适当地返回一个介于 28 和 31 之间的整数值。但是,这仅在 SQL Server 2012 中有效,这似乎比您在问题中标记的版本晚。

【讨论】:

  • 感谢您的帮助。这让我走上了正确的道路!
猜你喜欢
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 2020-02-18
  • 2020-12-01
  • 2011-04-29
  • 2020-11-21
  • 1970-01-01
相关资源
最近更新 更多