CTE而不是游标

问题描述 投票:0回答:2

有人能指出我用CTE代替光标的CTE示例吗?

我已经能够找到显示递归的所有示例。我不需要那个。我只是想逐步浏览一个记录集。

谢谢。

(编辑)

也许这是最好的另一种方式。我假设CTE或光标可能是获取我想要的数据的最佳方式,但这是一个例子。

如果我有一个包含用户ID,代码和日期的表,如下所示,其中userid不是主键。

2011-05-24 11:06:28.080     CODE1   199 
2011-05-24 11:06:28.080     CODE2   199 
2011-06-08 13:30:14.830     CODE2   209 
2011-06-08 13:30:14.313     CODE1   209 
2011-06-08 13:30:13.840     CODE2   209 
2011-06-08 13:30:13.450     CODE1   209 
2011-06-08 13:30:13.050     CODE2   209 
2010-05-07 10:45:06.800     CODE3   79  
2010-05-07 10:45:04.833     CODE3   79  
2010-10-15 07:30:16.193     CODE3   79  
2010-01-26 13:51:43.923     CODE3   79  
2010-01-26 13:51:43.923     CODE3   79  
2010-01-26 13:51:44.427     CODE3   79  
2010-01-26 13:51:45.103     CODE3   79  
2010-01-26 13:51:45.890     CODE3   79  
2010-01-26 13:51:46.733     CODE3   79  
2010-01-25 12:40:39.737     CODE3   81  
2010-01-25 12:40:40.890     CODE3   81  
2010-01-25 12:40:41.627     CODE3   81  
2010-01-25 12:40:43.277     CODE3   81  
2010-01-25 14:29:08.360     CODE3   81  
2010-01-21 19:36:34.660     CODE3   98  
2010-01-21 19:36:34.843     CODE3   98  
2010-01-21 19:36:35.013     CODE3   98  
2010-01-21 22:27:24.317     CODE3   83  
2010-01-21 22:31:21.443     CODE2   83  
2010-01-22 19:44:28.880     CODE3   83  

我想从这个表中选择每个用户最早的日期和代码是否可以使用CTE执行此操作?

我可以选择我按customerid分组的地方并获取MIN(日期字段),但我得到的是无法检索与该最早日期相关的代码,除非我将其添加到我的group by子句...然后当然我得到了多个客户的行,每个关联的代码。

我发现了一个解决方案,可以在我创建临时表的地方使用MIN(日期)和客户ID,通过在customerid上进行分组来填充它。然后我通过客户和日期字段将它连接到原始表来更新这个临时表,以获得与该行相关联的代码......但这似乎是一个黑客。

我想知道是否循环遍历原始表(按customerid和日期排序)以及每次我看到将该记录插入临时表的新客户ID时,将是一个更清晰的解决方案...特别是因为我找到的解决方案假设独特的日期时间/客户ID组合。

这是我现在使用的一个例子。它看起来像是一个黑客,我想知道是否一个cusor(我通常避免)或CTE将是一个更清洁的解决方案。

  DECLARE @Table1 TABLE 
(
    ClaimDate datetime, 
    VenueCode nvarchar(50), 
    CustomerID int
)
 INSERT INTO @Table1
  SELECT sc.CreateDate, v.code, sc.CSFCustomerID 
  FROM foo join foo1 on (snip)


DECLARE @Table2 TABLE
  ( 
  ClaimDate datetime,
  VenueCode nvarchar(50),
  CustomerID int)



 INSERT INTO @Table2
  select MIN(ClaimDate), NULL, CustomerID from @Table1 group by CustomerID

  UPDATE ft
  SET ft.SomeCode = t.VenueCode
FROM @Table2 ft
INNER JOIN @Table1 t ON ft.CustomerID = t.CustomerID
AND ft.ClaimDate = t.ClaimDate

谢谢,我保证我将来会更好地选择答案。

sql-server common-table-expression
2个回答
0
投票
with qry
(
SELECT Min(Date), userID
FROM TABLE
GROUP BY UserID
)

SELECT Table.*
FROM TABLE 
INNER JOIN qry on qry.UserID = Table.UserID AND qry.Date = Table.Date

0
投票

虽然它是相当古老的帖子,问题标题不适合说明你的主要任务,但最终:我想从这个表中选择每个用户最早的日期和代码是否可以使用CTE来做到这一点?

答案是肯定的。你可以试试这个:

-- CTE version of the SQL
WITH CTE (OldestClaimData, CustomerID)
AS
(
  SELECT
    MIN(ClaimDate), CustomerID
  FROM
    UserClaims
  GROUP BY
    CustomerID
)
SELECT DISTINCT
  UC.*
FROM
  UserClaims UC
INNER JOIN
  CTE ON (
    CTE.OldestClaimData=UC.ClaimDate
    AND
    CTE.CustomerID=UC.CustomerID
    AND 
    UC.VenueCode=(
      SELECT TOP 1
        VenueCode
      FROM
        UserClaims sub
      WHERE
        sub.ClaimDate=UC.ClaimDate
        AND
        sub.CustomerID=UC.CustomerID
    )
)
ORDER BY
    UC.CustomerID;

为了您的方便,我已将我的代码和您的代码放入SQL Fiddle

P.D。:你的accept rate工作。

© www.soinside.com 2019 - 2024. All rights reserved.