当前位置: 首页 > 面试题库 >

SQL:GROUP BY之后的SUM

叶卓君
2023-03-14
问题内容

样品表

CustomerId | VoucherId | CategoryId | StartDate | EndDate
-------------------------------------------------------------
        10 |         1 |          1 | 2013-09-01| 2013-09-30
        10 |         1 |          2 | 2013-09-01| 2013-09-30
        11 |         2 |          1 | 2013-09-01| 2013-11-30
        11 |         2 |          2 | 2013-09-01| 2013-11-30
        11 |         2 |          3 | 2013-09-01| 2013-11-30
        10 |         3 |          1 | 2013-10-01| 2013-12-31
        10 |         3 |          2 | 2013-10-01| 2013-12-31
        11 |         4 |          1 | 2013-12-01| 2014-04-30

在上面的示例记录中,我想找出客户凭证涵盖的总月数

我需要形式的输出

CustomerId | Months
--------------------
        10 | 4
        11 | 8

问题在于,凭证可以有多行用于不同的CategoryIds …

我计算出凭证涵盖的月份为DATEDIFF(MM,StartDate,EndDate)+1 …

当我应用SUM(DATEDIFF(MM,StartDate,EndDate))GROUP BY
VoucherId,StartDate,EndDate时,由于VoucherId的多行,我给出了错误的结果。

我得到这样的东西…

CustomerId | Months
--------------------
        10 | 8
        11 | 14

在这种情况下CategoryId是无用的

谢谢


问题答案:

[sql fiddle demo](http://www.sqlfiddle.com/#!3/811a6/3/0)

此SQL Fiddle解决了您的疑虑。您需要生成一个Calendar表,以便您可以将日期添加到其中。然后,您可以为每个客户计算不同的MonthYears。

create table test(
  CustomerId int,
  StartDate date,
  EndDate date
  )

insert into test
values 
  (10, '9/1/2013', '9/30/2013'),
  (10, '9/1/2013', '9/30/2013'),
  (11, '9/1/2013', '11/30/2013'),
  (11, '9/1/2013', '11/30/2013'),
  (11, '9/1/2013', '11/30/2013'),
  (10, '10/1/2013', '12/31/2013'),
  (10, '10/1/2013', '12/31/2013'),
  (11, '12/1/2013', '4/30/2014')

create table calendar(
  MY varchar(10),
  StartDate date,
  EndDate date
  )

insert into calendar
values 
  ('9/2013', '9/1/2013', '9/30/2013'),
  ('10/2013', '10/1/2013', '10/31/2013'),
  ('11/2013', '11/1/2013', '11/30/2013'),
  ('12/2013', '12/1/2013', '12/31/2013'),
  ('1/2014', '1/1/2014', '1/31/2014'),
  ('2/2014', '2/1/2014', '2/28/2014'),
  ('3/2014', '3/1/2014', '3/31/2014'),
  ('4/2014', '4/1/2014', '4/30/2014')

select
  t.CustomerId, 
  count(distinct c.MY)
from
  test t
  inner join calendar c
    on t.StartDate <= c.EndDate
      and t.EndDate >= c.StartDate
group by
  t.CustomerId


 类似资料:
  • 问题内容: 我想要使​​用几行: 在这一点上,当我期望得到每个生成的PK时,我得到了: 我希望对每个执行的插入操作都获得一个ResultSet一行,因此我可以生成每个PK。 我期望错了吗?难道我做错了什么?是否可以使用批处理以其他方式完成? 问题答案: 对批处理执行的支持是根据JDBC规范定义的实现。SQL Server驱动程序很可能不支持批量执行。 我试图在Microsoft网站上寻找明确的声明

  • 我们有一个Resteasy WebService。 我对JSON使用Jackson provider,在响应中使用传出JSON,在请求中使用传入JSON。 我还尝试在PostProcessInterceptor上使用注释。但它不起作用,甚至使用“解码器”优先级(这是最后一个)。 你知道吗?提前谢了。

  • 问题内容: 查看下面的示例代码 和 当我问到代码差异时,我并不是在说执行流程,这是显而易见的。 那么这些代码之间的 真正 区别是什么?建议何时 在 通话 前 使用您的代码,何时 在 通话 后 使用您的代码?我想在某些情况下这很重要。 问题答案: 您不应在之前放置任何代码,因为此方法可以使系统执行正确暂停应用程序所需的操作。您要在回调中执行的所有代码都应放在调用之后。希望这可以帮助。 活动报价: 注

  • 问题内容: 操作系统:Linux,语言:纯C 我将继续学习一般的C编程,在特殊情况下将学习UNIX下的C编程。 使用调用后,我检测到该函数的奇怪行为(对我而言)。 码 输出量 为什么第二个“ Hello”字符串出现在孩子的输出中? 是的,这恰恰是父母在开始时打印的内容,并带有父母的。 但!如果我们在每个字符串的末尾放置一个字符,则会得到预期的输出: 输出 : 为什么会发生?这是正确的行为还是错误?

  • 问题内容: 我试图在Java中实现UDP-Holepunching的简单草图以测试其概念,并稍后在我的C / C ++应用程序中使用它。 从Wikipedia来说,我的理解是:A和B是未定义网络结构背后的客户端,C是著名的公共可访问服务器。 A将数据包发送到服务器C,服务器保存其IP地址和端口。C将获得A的NAT的公共IP地址。这样做,A前面的NAT将创建一条路由,该路由会将此端口上的所有数据包传

  • 我通过从Listview中删除默认分隔符来设置我的自定义分隔符: 并在(保留项目图标;保留项目文本): 正因为如此,我在每个项目文本下都有客户分隔符(视图),但在项目图标下没有。 在列表中的最后一项之后,我希望分割符也可以在这样的图标下显示: 以下是通货膨胀的原因: