【问题标题】:Iterating through every row efficient?遍历每一行是否有效?
【发布时间】:2016-12-30 06:12:30
【问题描述】:

假设我有下表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 所述那样遍历每一行,还是有更有效的方法?

【问题讨论】:

  • 如何确定 T1 中的哪些值用于 ABC
  • @RaduGheorghiu:请看一下我提供的伪代码。
  • 我永远不会遍历一个表,如果你必须这样做,那么你的设计或算法很糟糕。
  • 您的各种条件似乎是互斥的,仅取决于当前行中的数据。我看不出有什么理由你不会在单个 SELECT 中并行计算所有值而不是迭代。

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


【解决方案1】:

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

 ;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 table

【讨论】:

    【解决方案2】:

    这是您不应该写入表的内容(除非没有数百万行并且您需要它来提高性能...)。您应该像这样即时获取这些信息:

    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)来捕获无效数据(例如负值)。

    【讨论】:

      猜你喜欢
      • 2020-06-12
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 2014-06-29
      • 1970-01-01
      相关资源
      最近更新 更多