【问题标题】:Complex SQL query with group by and two rows in one具有 group by 和两行合二为一的复杂 SQL 查询
【发布时间】:2010-03-24 16:01:42
【问题描述】:

好的,我需要帮助。我通常很擅长 SQL 查询,但这让我感到困惑。顺便说一句,这不是家庭作业,它是 Access 数据库中的真实情况,我自己写了下面的要求。


这是我的表格布局。如果重要的话,它在 Access 2007 中;我正在使用 SQL 编写查询。

Id (primary key)
PersonID (foreign key)
EventDate
NumberOfCredits
SuperCredits (boolean)

人们会参加一些活动。他们可以在一次活动中获得普通学分或超级学分,或两者兼而有之。如果该行表示在活动中获得的一些超级积分,则 SuperCredits 列为 true,如果表示正常积分,则为 false。

例如,如果有一个人 174 参加的活动,并且他们在该活动中获得了 3 个普通积分和 1 个超级积分,则会将以下两行添加到表中:

ID PersonID EventDate NumberOfCredits SuperCredits
1  174      1/1/2010  3               false
2  174      1/1/2010  1               true

这个人也有可能在活动中做了两件不同的事情,所以一个活动可能有两个以上的列,它可能看起来像这样:

ID PersonID EventDate NumberOfCredits SuperCredits
1  174      1/1/2010  1               false
2  174      1/1/2010  2               false
3  174      1/1/2010  1               true

现在我们要打印一份报告。以下是报告的列:

PersonID
LastEventDate
NumberOfNormalCredits
NumberOfSuperCredits

报告将每人一行。该行将显示此人参加的最新活动,以及此人在该活动中获得的普通积分和超级积分。

我要求你编写或帮助我编写 SQL 查询以选择数据和 GROUP BY 和 SUM() 等等。 或者,如果这是由于某种原因不可能,以及如何组织我的数据以使其成为可能。


这非常令人困惑,如果您不花时间来解决它,我理解。我试图尽可能地简化它,但如果你试一试并需要澄清,一定要问任何问题。我会努力弄清楚,但我真的很难处理,这超出了我的经验......

【问题讨论】:

    标签: sql ms-access ms-access-2007


    【解决方案1】:

    创建以下查询/视图(比如称为 PersonLastEvents):

    select PersonId, max(EventDate) as LastEventDate
    from Events
    group by PersonId
    

    然后你就可以通过下面的方式获取你需要的数据了。我对 Access 并不完全熟悉,因此您可能需要修改一些语法,但希望这会给您提供一种方法。

    select l.PersonId, l.LastEventDate, 
      sum(case when e.SuperCredits = 'false' then e.NumberOfCredits end) 
        as NumberOfNormalCredits
      sum(case when e.SuperCredits = 'true' then e.NumberOfCredits end) 
        as NumberOfSuperCredits
    from PersonLastEvents l
    join Events e on l.PersonId = e.PersonId and l.LastEventDate = l.EventDate
    group by l.PersonId, l.LastEventDate
    

    顺便说一句,将表更改为具有两个数字列(NormalCredits、SuperCredits)可能更容易,因为它允许您根据需要简单地对列进行 sum()。

    【讨论】:

    • 非常感谢,我永远不会想到这一点,但它工作得很好!!我唯一需要更改的是 Access 没有 case 语句,而是使用 switch(condition, value)。我希望有办法给你额外的声誉!
    • Access/Jet/ACE SQL 不支持 CASE,所以这个答案不起作用。请不要使用您尚未针对问题中涉及的数据库引擎进行测试的 SQL 方言回答问题。 -1
    • CASE 也可以用 iif() 代替,如果它只是一个布尔测试
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-21
    • 1970-01-01
    相关资源
    最近更新 更多