【问题标题】:Counting specific values across columns within SQL Server 2008 view在 SQL Server 2008 视图中跨列计算特定值
【发布时间】:2013-03-20 19:02:42
【问题描述】:

我有以下数据:


   ID Column1 Column2 Column3 Column4 Column5
   001   A        C       D        A      B
   002   A        D       A        B      A
   003   B        K       Q        C      Q
   004   A        K       E        E      B

我想在视图中创建一个新列,它为我提供每行 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”计数,而不是跨行聚合。有什么想法吗?

【问题讨论】:

    标签: sql-server tsql view count sql-server-2008-r2


    【解决方案1】:

    您可以使用多个CASE 表达式来计算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
    

    SQL Fiddle with Demo

    【讨论】:

    • @bluefeet 罢工 :) 我能说什么。
    【解决方案2】:

    对于这种情况,我更喜欢使用 CROSS APPLY 来执行中间逻辑 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 个地方改变你计算的值,并且如果需要添加更多的列是非常容易的。

    看到这个working in a Sql Fiddle

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

    如果由于某种原因无法更改架构,则可以考虑创建视图:

    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;
    

    【讨论】:

    • 谢谢!我同意表格设计不是最理想的,您所描述的就是它应该的方式。问题是源系统(REDCap)只有一对一的表结构,所以这些重复值存储在单独的列中,所以我按原样使用它,目前不对其进行转换。
    • 顺便试了一下,效果很好,谢谢。我会用这个作为解决方案,但另一个是先发布的。我将它保存到另一个时间,我会在以后运行它。
    • 请查看我的更新以获得更多想法。感谢您查看代码。
    【解决方案3】:
    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
    

    【讨论】:

      【解决方案4】:

      您可以使用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
      

      【讨论】:

        猜你喜欢
        • 2020-10-19
        • 1970-01-01
        • 2011-04-11
        • 1970-01-01
        • 1970-01-01
        • 2014-10-06
        • 2015-07-08
        • 2022-01-11
        相关资源
        最近更新 更多