在 SQL Server 2008 视图中跨列计算特定值
Posted
技术标签:
【中文标题】在 SQL Server 2008 视图中跨列计算特定值【英文标题】:Counting specific values across columns within SQL Server 2008 view 【发布时间】: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”计数,而不是跨行聚合。有什么想法吗?
【问题讨论】:
【参考方案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
【讨论】:
以上是关于在 SQL Server 2008 视图中跨列计算特定值的主要内容,如果未能解决你的问题,请参考以下文章