具有多个子查询的SELECT查询计数

pix*_*wiz 3 sql-server select count sql-server-2012

我刚刚为报告编写了这个查询.但我最初在每个子查询中都没有使用日期范围过滤器编写它.但那没用.所以我将它添加到每个子查询中.这很有效,但我不是每次都不想重复它,是否有语法来做同样的事情更简单?

 SELECT Count(r.id)                       AS cnt_total,
   (SELECT Count(r1.entity_id)
    FROM   auto_reminders_members r1
    WHERE  r1.reminder_id = r.reminder_id
           AND r1.date_last_reminder BETWEEN CONVERT(DATETIME, '03/28/2013',
                                             101)
                                             AND
               CONVERT(DATETIME,
               '03/28/2013' + ' 23:59:59.997 ', 101)
           AND r1.action = 'notnow') AS cnt_notnow,
   (SELECT Count(r1.entity_id)
    FROM   auto_reminders_members r1
    WHERE  r1.reminder_id = r.reminder_id
           AND r1.date_last_reminder BETWEEN CONVERT(DATETIME, '03/28/2013',
                                             101)
                                             AND
               CONVERT(DATETIME,
               '03/28/2013' + ' 23:59:59.997 ', 101)
           AND r1.action = 'insert') AS cnt_insert,
   (SELECT Count(r1.entity_id)
    FROM   auto_reminders_members r1
    WHERE  r1.reminder_id = r.reminder_id
           AND r1.date_last_reminder BETWEEN CONVERT(DATETIME, '03/28/2013',
                                             101)
                                             AND
               CONVERT(DATETIME,
               '03/28/2013' + ' 23:59:59.997 ', 101)
           AND r1.action = 'update') AS cnt_update,
   (SELECT Count(r1.entity_id)
    FROM   auto_reminders_members r1
    WHERE  r1.reminder_id = r.reminder_id
           AND r1.date_last_reminder BETWEEN CONVERT(DATETIME, '03/28/2013',
                                             101)
                                             AND
               CONVERT(DATETIME,
               '03/28/2013' + ' 23:59:59.997 ', 101)
           AND r1.action = 'verify') AS cnt_verify
FROM   auto_reminders_members r
WHERE  r.reminder_id = 1
       AND r.date_last_reminder BETWEEN CONVERT(DATETIME, '03/28/2013', 101) AND
                                            CONVERT(DATETIME,
                                            '03/28/2013' + ' 23:59:59.997 ', 101
                                            )
GROUP  BY r.reminder_id  
Run Code Online (Sandbox Code Playgroud)

Nat*_*ate 11

如果没有所有子查询,这是一种方法

SELECT  Count(r.id) AS cnt_total,
        sum(case when r.action = 'notnow' then 1 else 0 end) as 'cnt_notnow',
        sum(case when r.action = 'insert' then 1 else 0 end) as 'cnt_insert',
        sum(case when r.action = 'update' then 1 else 0 end) as 'cnt_update',
        sum(case when r.action = 'verify' then 1 else 0 end) as 'cnt_verify'        
FROM    auto_reminders_members r

WHERE  r.reminder_id = 1
       AND CONVERT(DATE, r.date_last_reminder) = '20130328'
Run Code Online (Sandbox Code Playgroud)

我还清理了一下查询,删除了组,因为这将始终为1,并更改日期比较以避免使用逻辑之间的混乱(感谢Aaron的评论)

  • 仅供参考[`BETWEEN`仍然很糟糕](http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx) ,也没有理由返回`reminder_id`列,如果它是常量(`1`),不要介意`GROUP BY`它. (2认同)