Sql server 如何在SELECT COUNT语句中使用CASE语句?

Sql server 如何在SELECT COUNT语句中使用CASE语句?,sql-server,tsql,count,case,Sql Server,Tsql,Count,Case,我需要做一个案例陈述 根据变量值的不同,它需要从表中选择正确的列 StartDate和EndDate是不同的变量 我创建了一个名为Region的变量,它应该确定查询选择的列 编辑:英格兰和威尔士的地区可以是“EW”,苏格兰的地区可以是“SC”,北爱尔兰的地区可以是“NI”。 如果为EW,则应选择第1列,第2列为SC,第3列为NI SELECT COUNT(COLUMN1) FROM bankholidays WHERE COLUMN1 BETWEEN @StartDate AND @EndDa

我需要做一个案例陈述

根据变量值的不同,它需要从表中选择正确的列

StartDate和EndDate是不同的变量

我创建了一个名为Region的变量,它应该确定查询选择的列

编辑:英格兰和威尔士的地区可以是“EW”,苏格兰的地区可以是“SC”,北爱尔兰的地区可以是“NI”。 如果为EW,则应选择第1列,第2列为SC,第3列为NI

SELECT
COUNT(COLUMN1)
FROM  bankholidays
WHERE COLUMN1 BETWEEN @StartDate AND @EndDate)

假设您要计算
Column1
在开始日期和结束日期之间的记录数,则以下操作应有效:

SELECT SUM(CASE WHEN COLUMN1 BETWEEN @StartDate AND @EndDate
           THEN 1 ELSE 0 END) AS tally
FROM bankholidays
这种方法称为条件聚合,通常还使用
GROUPBY
子句

更新:

要处理
@Region
变量,查询可能如下所示:

SELECT CASE WHEN @Region = 'val1' THEN COLUMN1
            WHEN @Region = 'val2' THEN COLUMN2
            WHEN @Region = 'val3' THEN COLUMN3
       END AS new_column   
FROM bankholidays

请注意,我没有尝试将其与第一个查询结合起来,因为它会将聚合函数与非聚合项混合在一起,并且可能没有意义。

假设您要计算
Column1
在开始日期和结束日期之间的记录数,那么以下操作应该可以工作:

SELECT SUM(CASE WHEN COLUMN1 BETWEEN @StartDate AND @EndDate
           THEN 1 ELSE 0 END) AS tally
FROM bankholidays
这种方法称为条件聚合,通常还使用
GROUPBY
子句

更新:

要处理
@Region
变量,查询可能如下所示:

SELECT CASE WHEN @Region = 'val1' THEN COLUMN1
            WHEN @Region = 'val2' THEN COLUMN2
            WHEN @Region = 'val3' THEN COLUMN3
       END AS new_column   
FROM bankholidays

请注意,我没有尝试将其与第一个查询结合使用,因为它会将聚合函数与非聚合项混合使用,并且可能没有意义。

如果要对给定列值介于两个日期之间的记录进行动态计数,请使用动态查询:

DECLARE @column NVARCHAR(MAX)
DECLARE @sql NVARCHAR(MAX)

SET @column = 'COLUMN1' --Set your desired column here
SET @sql = 'SELECT COUNT(*) FROM bankholidays WHERE ' + @column + ' BETWEEN ''' + CONVERT(NVARCHAR,@StartDate,121) + ''' AND ''' + CONVERT(NVARCHAR,@EndDate,121) + ''''

EXEC @sql

如果要对给定列值介于两个日期之间的记录进行动态计数,请使用动态查询:

DECLARE @column NVARCHAR(MAX)
DECLARE @sql NVARCHAR(MAX)

SET @column = 'COLUMN1' --Set your desired column here
SET @sql = 'SELECT COUNT(*) FROM bankholidays WHERE ' + @column + ' BETWEEN ''' + CONVERT(NVARCHAR,@StartDate,121) + ''' AND ''' + CONVERT(NVARCHAR,@EndDate,121) + ''''

EXEC @sql

如果您想
计数
并动态检查列,请尝试此

DECLARE @sql VARCHAR(500), 
    @Region VARCHAR(100) = 'COLUMN2', --It can be Column1, Column2.....
    @StartDate DATETIME = '2016-04-10',
    @EndDate DATETIME = '2016-04-15'

SET @sql = '
    SELECT
    COUNT(' + @Region + ')
    FROM  bankholidays
    WHERE ' + @Region + ' BETWEEN ''' + CAST(@StartDate AS VARCHAR) + ''' AND ''' + CAST(@EndDate AS VARCHAR) + ''''

EXEC (@SQL)
--查询执行如下

SELECT
COUNT(COLUMN2)--It can be Column1, Column2.....
FROM  bankholidays
WHERE COLUMN2 BETWEEN 'Apr 10 2016 12:00AM' AND 'Apr 15 2016 12:00AM'

如果您想
计数
并动态检查列,请尝试此

DECLARE @sql VARCHAR(500), 
    @Region VARCHAR(100) = 'COLUMN2', --It can be Column1, Column2.....
    @StartDate DATETIME = '2016-04-10',
    @EndDate DATETIME = '2016-04-15'

SET @sql = '
    SELECT
    COUNT(' + @Region + ')
    FROM  bankholidays
    WHERE ' + @Region + ' BETWEEN ''' + CAST(@StartDate AS VARCHAR) + ''' AND ''' + CAST(@EndDate AS VARCHAR) + ''''

EXEC (@SQL)
--查询执行如下

SELECT
COUNT(COLUMN2)--It can be Column1, Column2.....
FROM  bankholidays
WHERE COLUMN2 BETWEEN 'Apr 10 2016 12:00AM' AND 'Apr 15 2016 12:00AM'
1) 如果您不关心从计数中排除null,则不需要在count语句中指定列名。i、 e

select count(Column1)
将给出与相同的结果

select count(1)

只要column1没有空值。如果column1确实包含空值,则不会对其进行计数(因此,如果有10条记录,其中3条记录在column1中具有空值,则使用
count(column1)
会得到7,或者使用其他方法会得到10

我首先提到这一点,就好像您关心空值一样,然后更改此处使用的列是有意义的;如果您不关心空值,请使用更简单的逻辑,即只
count(1)
/
connt(*)

综上所述,以下是如何更改该列:

select count(
    case @Region 
        when 1 then Column1 
        when 2 then Column2 
        else Column3 
    end
)
2) 如果要更改WHERE语句中使用的列,有两种方法:

SELECT COUNT(1)
FROM  bankholidays
WHERE case @Region 
    when 1 then Column1 
    when 2 then Column2 
    else Column3        
end BETWEEN @StartDate AND @EndDate

就我个人而言,我更喜欢上面的第一种风格,因为它涉及较少的重复;但是,第二种样式提供了对不同列使用不同开始和结束日期的选项,或者也可以添加其他逻辑,因此仍然值得注意。

1)如果您不关心从计数中排除空值,则不需要在count语句中指定列名。i、 e

select count(Column1)
declare  @Region  varchar(10)
set @Region='EW'

SELECT 
COUNT(*) OVER(PARTITION BY 1) as TotalRows,
Case  
    when @Region ='EW' THEN   Column1 
    when @Region ='SC' THEN   Column2
    when @Region ='NI' THEN   Column3
end as [NewColumn]
FROM [BankHolidays] 
WHERE COLUMN1 BETWEEN @StartDate AND @EndDate
将给出与相同的结果

select count(1)

只要column1没有空值。如果column1确实包含空值,则不会对其进行计数(因此,如果有10条记录,其中3条记录在column1中具有空值,则使用
count(column1)
会得到7,或者使用其他方法会得到10

我首先提到这一点,就好像您关心空值一样,然后更改此处使用的列是有意义的;如果您不关心空值,请使用更简单的逻辑,即只
count(1)
/
connt(*)

综上所述,以下是如何更改该列:

select count(
    case @Region 
        when 1 then Column1 
        when 2 then Column2 
        else Column3 
    end
)
2) 如果要更改WHERE语句中使用的列,有两种方法:

SELECT COUNT(1)
FROM  bankholidays
WHERE case @Region 
    when 1 then Column1 
    when 2 then Column2 
    else Column3        
end BETWEEN @StartDate AND @EndDate

就我个人而言,我更喜欢上面的第一种风格,因为它涉及较少的重复;然而,第二种样式提供了对不同列使用不同的开始和结束日期的选项,或者添加其他逻辑,因此仍然值得注意

declare  @Region  varchar(10)
set @Region='EW'

SELECT 
COUNT(*) OVER(PARTITION BY 1) as TotalRows,
Case  
    when @Region ='EW' THEN   Column1 
    when @Region ='SC' THEN   Column2
    when @Region ='NI' THEN   Column3
end as [NewColumn]
FROM [BankHolidays] 
WHERE COLUMN1 BETWEEN @StartDate AND @EndDate
试试这样的


尝试类似这样的方法

也就是说,您想动态选择列?请提供示例数据和预期数据您所依赖的列是否重要;i、 e.您是否关心空值,或者
count(*)
count(1)
(功能相同)是否正常?或者,您感兴趣的是WHERE语句中的列吗?也就是说,您希望动态选择列?请提供示例数据和预期数据您所依赖的列是否重要;i、 e.您是否关心空值,或者
count(*)
count(1)
(功能相同)是否正常?或者,您感兴趣的是WHERE语句中的列吗?我只建议将动态sql作为最后手段,特别是如果将其作为存储过程或查询编写,将来可能会维护它。就其一而言,还不错。我不是说你错了,而是出于兴趣——为什么?因为很难维护,尤其是当查询随着时间的推移而增长时。我曾经做过一些不需要存在的动态SQL的噩梦。当您有很长的对象名或记不起函数中哪个参数的位置时,您也无法获得intellisense。谁愿意花15-20分钟来解决有时动态的混乱,只是为了稍微改变一下加入?如果你可以不用它,就不用它。将动态SQL构建留给ORM来完成,或者使用同义词,或者只是……什么的。我只建议将动态SQL作为最后手段,特别是如果将其作为存储过程或将来可能维护的查询来编写的话。一次性的