迭代每一行都有效吗?

时间:2016-08-23 12:09:20

标签: sql sql-server tsql triggers sql-server-2008-r2

假设我有下表T1

| col1 | col2 |
|------|------|
| 0    | 0    | // A++
| 3    | 123  | // B++
| 0    | 5    | // C++
| 8    | 432  | // A++
| 0    | 4    | // B++

我现在需要创建一个触发器(在INSERT上),分析每一行,增加一个计数器(见下文),用计数器的值填充表T2

IF col1 = 0 AND col2 = 0
    A++
ELSE IF col1 = 0 col2 > 0
    B++
ELSE IF col1 > 0
    C++

在这种情况下,T2看起来像是:

| id | A | B | C |
|----|---|---|---|
| 1  | 1 | 2 | 2 |

我的问题更多的是关于设计:我应该如HERE所描述的那样迭代每一行,还是有更有效的方式?

2 个答案:

答案 0 :(得分:2)

在触发器中尝试这样的事情

 ;with data as
 (
SELECT Sum(CASE WHEN col1 = 0 AND col2 = 0 THEN 1 END) AS a,
       Sum(CASE WHEN col1 = 0 AND col2 > 0 THEN 1 END) AS b,
       Sum(CASE WHEN col1 > 0 THEN 1 END) AS c
FROM   (VALUES (0, 0 ),
               (3, 123 ),
               (0, 5 ),
               (8, 432 ),
               (0, 4 ) ) tc ( col1, col2 ) 
               )
UPDATE yt
SET    a = dt.a,
       b = dt.b,
       c = dt.c
FROM   yourtable yt
       JOIN data dt
         ON a.id = b.id 

这不需要逐行迭代。用Inserted

替换表值构造函数

答案 1 :(得分:1)

这是你不应该写入表格的东西(除非没有数百万行,你需要这个以表现......)。您应该像这样在运行中获取此信息:

DECLARE @T1 TABLE(col1 INT,col2 INT);
INSERT INTO @T1(col1,col2) VALUES
 (0,0)
,(3,123)
,(0,5)
,(8,432)
,(0,4);

SELECT p.*
FROM
(
    SELECT CASE WHEN col1=0 AND col2=0 THEN 'A'
                WHEN col1=0 AND col2>0 THEN 'B'
                WHEN col1>0 THEN 'C' END AS Category
    FROM @T1 AS t
) AS tbl
PIVOT
(
    COUNT(Category) FOR Category IN(A,B,C) 
) AS p

结果

A   B   C
1   2   2

我建议您添加另一个选项(使用ELSE)来捕获无效数据(例如,否定值)。