2

我需要制定一个每天晚上执行的预定工作。我已经完成了任务,但必须使用 While 循环。这让我感到“内疚”。我需要一些关于如何将此操作转换为基于集合的操作并提高性能的建议。

我的表看起来像(尽可能简化它):

T_POOL
PoolID | ContactID | ContactState
  1    |     1     |      1
  1    |     2     |      1
  1    |     3     |      1
  2    |     4     |      2
  2    |     5     |      3

 T_POOL_DEC
 PoolID | Layer4ID
   1    |    1
   2    |    3
   3    |    5

 T_LAYER4
 Layer4ID | ConditionValue1(Count) | ConditionValue2(Month)
    1     |       5                | 3

我使用 while 循环的原因是检索相对于 PoolID 的 ContactID 值(作为一个组)。在临时表中存储不同的 poolID 值并在循环中获取这些 poolID 值。所以我的 While 循环循环通过 PoolID 的不同值(不是逐行循环遍历所有表)而且我正在执行更新操作,这可以证明如下:

  While (True)
    Take Next @PoolID

    Update T_Pool TP SET ContactState ={some value} 
    INNER JOIN T_POOL_DEC PD ON PD.PoolID = TP.PoolID
    INNER JOIN T_LAYER4 L4 ON L4.Layer4ID = PD.Layer4ID
    Where {COUNT(TP.ContactID) >= L4.ConditionValue1 
    AND ContactID.CreateDate >=DATEADD(MM,L4.ConditionValue2*-1,GETDATE()}
    AND PoolID = @PoolID

    If it has passed through all available PoolIDs, break;
  END

我希望我能尽可能清楚地展示这种情况,因为我无法在这里写下所有的查询。

编辑评论: 忘了补充,阻止我更新整个表的是,PoolID 是上面的 FK。每个 PoolID 都有一个 Layer4ID,我正在根据 PoolID 的 Layer4 值对池中的每个 ContactID 进行一些计算(例如根据状态计算池中的每个联系人,并检查计数结果是否等于或大于它的 Pool 的 Layer4 值。编辑我的表格演示部分更清楚。

所以从上面可以看出,每个Pool都有一个Layer4ID。并且每个 Layer4 都有一些条件,在这种情况下,它们都是整数(ConditionValue1 表示要更新的 ContactID 的最小计数(我的意思是更新 T_POOL 表中的状态),而 ConditionValue2 表示每个联系人的当前日期过去的月数被视为有效。(以更新其状态)-从其自己的表中检索 ContactID 的创建日期。-

Edit2 在我的示例查询中添加了一些连接(忽略语法错误、分组等)

编辑3

我当前的查询如下所示:简单地说,这需要从 while 循环中“释放”,即消除 @PoolID 的使用。

UPDATE T_POOL SET ContactState= 4
WHERE PoolID= @PoolID AND ContactState=2
AND EXISTS(
SELECT T.ContactID FROM(
   SELECT TP.ContactID,
      L4.ConditionValue1,
      COUNT(TP.ContactID) OVER (PARTITION BY TP.PoolID) AS TOTAL_CONTACT_COUNT
   FROM Contact C
   INNER JOIN T_POOL TP ON TP.ContactID= C.ContactID
   INNER JOIN T_POOL_DEC PD ON PD.PoolID = TP.PoolID
       INNER JOIN T_LAYER4 L4 ON L4.Layer4ID = PD.Layer4ID
   WHERE PD.PoolID= @PoolID AND TP.State=2 AND TP.LOG_STATUS NOT IN (9,10) AND  C.LOG_CREATE_DATE >= DATEADD(MM,L4.ConditionValue2*-1,GETDATE()))T 

 WHERE T.TOTAL_CONTACT_COUNT>=T.ConditionValue1 AND C.ContactID= ContactID)
4

0 回答 0