如何忽略 CTE Select 语句中的重复行?

Rah*_*awe -2 sql-server t-sql

我试图忽略来自 CTE 的重复行,但我无法做到这一点,似乎 CTE 不允许使用ROWNUM()变量到WHERE子句,因为它在尝试这样做时显示“无效的列名 'numrows' ”错误.

SELECT在 a 中使用时如何忽略重复的行CTE

SQL查询:

DECLARE @BatchID uniqueidentifier = NEWID();
DECLARE @ClusterID SMALLINT = 1;
DECLARE @BatchSize integer = 20000;
DECLARE @myTableVariable TABLE(
    EventID BIGINT,
    HotelID int,
    BatchStatus varchar(50),
    BatchID uniqueidentifier);

WITH PendingExtResSvcEventsData_Batch AS (
    SELECT TOP (@BatchSize) t.EventID, t.HotelID, t.BatchStatus, t.BatchID,
        ROW_NUMBER() OVER (PARTITION BY t.EventID ORDER BY t.EventID) numrows 
    FROM ExtResSvcPendingMsg t WITH (NOLOCK)
    WHERE t.ClusterID = @ClusterID
      AND numrows = 1
      -- Exclude ExtResSvcEventID and HotelID,
      -- which are partly included in in-progress batch.
      AND NOT EXISTS (
          select 1 from ExtResSvcPendingMsg t2
          where t2.BatchStatus = 'Batched'
            and t2.EventID = t.EventID and t2.HotelID = t.HotelID
          )
    )
UPDATE PendingExtResSvcEventsData_Batch
   SET BatchStatus='Batched',
       BatchID = @BatchID
OUTPUT INSERTED.* INTO @myTableVariable --WHERE numrows = 1

SELECT e.ExtResSvcEventID, e.HotelID, e.ID1, e.ID2, e.ExtResSvcEventType, e.HostID,
       e.StatusCode, e.ChannelID, e.RequestAtTime, e.ProcessTime, e.DateBegin, e.DateEnd,
       e.StatusMsg, em.MsgBodyOut, em.MsgBodyIn, e.ChannelResID 
FROM  ExtResSvcEvent e WITH (NOLOCK)
INNER JOIN @myTableVariable t ON e.ExtResSvcEventID = t.EventID
INNER JOIN ExtResSvcEventXML em WITH (NOLOCK) ON t.EventID = em.ExtResSvcEventID
ORDER BY e.ExtResSvcEventID
Run Code Online (Sandbox Code Playgroud)

And*_*y M 5

不要INSERTED.*在这里使用:

OUTPUT INSERTED.* INTO @myTableVariable
Run Code Online (Sandbox Code Playgroud)

相反,明确列出列:

OUTPUT INSERTED.EventID,
       INSERTED.HotelID,
       INSERTED.BatchStatus,
       INSERTED.BatchID
INTO @myTableVariable
Run Code Online (Sandbox Code Playgroud)

*方法的所有目标数据集的列。您案例中的目标数据集是一个 CTE,除了普通列之外,它还返回一个计算列。该INSERTED.*语法包括计算列太多,但引用计算的列在这方面是不允许的。列出所有必需的列可以明确解决该问题。

可以numrows在该 UPDATE 上使用过滤器(但不能在 CTE 内使用)。numrows除了 OUTPUT 子句和 SET 子句中赋值的左侧,该引用在任何地方都有效。

这是一个演示,它无耻地借用了 ypercube?? 的设置以及他的 UPDATE 语句。