Sql server 在SQL Server 2008视图中跨列计算特定值

Sql server 在SQL Server 2008视图中跨列计算特定值,sql-server,tsql,view,count,sql-server-2008-r2,Sql Server,Tsql,View,Count,Sql Server 2008 R2,我有以下数据: 我想在一个视图中创建一个新列,该视图给出每行5个源列中的“a”计数。结果应该如下所示: ID Column1 Column2 Column3 Column4 Column5 SumOfA 001 A C D A B 2 002 A D A B A 3 003 B K Q

我有以下数据:



我想在一个视图中创建一个新列,该视图给出每行5个源列中的“a”计数。结果应该如下所示:

    ID Column1 Column2 Column3 Column4 Column5  SumOfA
    001   A        C       D        A      B       2
    002   A        D       A        B      A       3
    003   B        K       Q        C      Q       0
    004   A        K       E        E      B       1


我在这里看到了几个示例,但它们返回跨记录的“A”实例-我希望跨列的“A”计数,而不是跨行聚合。有什么想法吗

您可以使用多个
CASE
表达式来计算
A
值:

SELECT 
(CASE WHEN Column1 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column2 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column3 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column4 = 'A' THEN 1 ELSE 0 END 
+ CASE WHEN Column5 = 'A' THEN 1 ELSE 0 END) AS SumOfA
FROM myTable
select id,
  column1, 
  column2,
  column3,
  column4, 
  column5,
  case when column1 = 'A' then 1 else 0 end +
  case when column2 = 'A' then 1 else 0 end +
  case when column3 = 'A' then 1 else 0 end +
  case when column4 = 'A' then 1 else 0 end +
  case when column5 = 'A' then 1 else 0 end TotalA
from yourtable

请参见您可以使用多个
大小写
表达式来计算
A
值:

select id,
  column1, 
  column2,
  column3,
  column4, 
  column5,
  case when column1 = 'A' then 1 else 0 end +
  case when column2 = 'A' then 1 else 0 end +
  case when column3 = 'A' then 1 else 0 end +
  case when column4 = 'A' then 1 else 0 end +
  case when column5 = 'A' then 1 else 0 end TotalA
from yourtable

请参见您可以使用
CASE
语句来实现这一点:

SELECT 
    column1, column2, column3, column4, column5,
    (CASE WHEN Column1 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column2 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column3 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column4 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column5 = 'A' THEN 1 ELSE 0 END) AS TotalSum  
FROM yourTable

您可以使用
CASE
语句来实现这一点:

SELECT 
    column1, column2, column3, column4, column5,
    (CASE WHEN Column1 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column2 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column3 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column4 = 'A' THEN 1 ELSE 0 END   
     + CASE WHEN Column5 = 'A' THEN 1 ELSE 0 END) AS TotalSum  
FROM yourTable

对于这种情况,我更喜欢使用crossapply来执行中间逻辑UNPIVOT

SELECT
   *
FROM
   dbo.YourTable T
   CROSS APPLY (
      SELECT Count(*)
      FROM (VALUES (Column1), (Column2), (Column3), (Column4), (Column5)) C (Val)
      WHERE Val = 'A'
   ) A (Cnt)
这还有一个优点,即可以更改仅在一个位置而不是在5个位置计算的值,并且如果需要,可以非常轻松地添加更多列

看到这个了吗

但是,您正在努力构建此查询,这表明表设计可能不是最好的。如果列名本身包含数据(例如时间段、区域或其他类型的类似值),则几乎可以肯定设计是次优的。我强烈建议您存储未插入的数据——每个值使用一行和一列,并使用一个新列指示数据来自哪个原始列

如果不能根据任何原因更改架构,可以考虑创建视图:

CREATE VIEW dbo.YourTableUnpivoted
SELECT
   T.ID,
   C.*
FROM
   dbo.YourTable T
   CROSS APPLY (VALUES
      ('Column1', Column1),
      ('Column2', Column2),
      ('Column3', Column3),
      ('Column4', Column4),
      ('Column5', Column5)
   ) C (Col, Val);
(您也可以使用
PIVOT
操作符。)然后您可以将其用作重新设计的表:

SELECT
   ID,
   Count(*)
FROM
   dbo.YourTableUnpivoted
WHERE
   Val = 'A'
GROUP BY
   ID;

对于这种情况,我更喜欢使用crossapply来执行中间逻辑UNPIVOT

SELECT
   *
FROM
   dbo.YourTable T
   CROSS APPLY (
      SELECT Count(*)
      FROM (VALUES (Column1), (Column2), (Column3), (Column4), (Column5)) C (Val)
      WHERE Val = 'A'
   ) A (Cnt)
这还有一个优点,即可以更改仅在一个位置而不是在5个位置计算的值,并且如果需要,可以非常轻松地添加更多列

看到这个了吗

但是,您正在努力构建此查询,这表明表设计可能不是最好的。如果列名本身包含数据(例如时间段、区域或其他类型的类似值),则几乎可以肯定设计是次优的。我强烈建议您存储未插入的数据——每个值使用一行和一列,并使用一个新列指示数据来自哪个原始列

如果不能根据任何原因更改架构,可以考虑创建视图:

CREATE VIEW dbo.YourTableUnpivoted
SELECT
   T.ID,
   C.*
FROM
   dbo.YourTable T
   CROSS APPLY (VALUES
      ('Column1', Column1),
      ('Column2', Column2),
      ('Column3', Column3),
      ('Column4', Column4),
      ('Column5', Column5)
   ) C (Col, Val);
(您也可以使用
PIVOT
操作符。)然后您可以将其用作重新设计的表:

SELECT
   ID,
   Count(*)
FROM
   dbo.YourTableUnpivoted
WHERE
   Val = 'A'
GROUP BY
   ID;

@蓝脚打击:)我能说什么。@bluefeet打击:)我能说什么。谢谢!我同意桌子的设计是次优的,你所描述的是它应该是的方式。问题是,源系统(REDCap)只有一个toone表结构,所以这些重复值存储在单独的列中,所以我按原样使用它,目前不转换它。顺便说一句,我试过了,效果很好,谢谢。我本想用这个作为解决方案,但另一个是先发布的。我会把它保存到另一个时间,稍后我会看到它。请查看我的更新以了解更多想法。谢谢你查看代码。谢谢!我同意桌子的设计是次优的,你所描述的是它应该是的方式。问题是,源系统(REDCap)只有一个toone表结构,所以这些重复值存储在单独的列中,所以我按原样使用它,目前不转换它。顺便说一句,我试过了,效果很好,谢谢。我本想用这个作为解决方案,但另一个是先发布的。我会把它保存到另一个时间,稍后我会看到它。请查看我的更新以了解更多想法。谢谢你检查代码。