【问题标题】:Recursive SQL query - using results from query within query递归 SQL 查询 - 在查询中使用查询结果
【发布时间】:2012-12-23 21:42:52
【问题描述】:

我正在运行 SQL Server 2012,这就是我需要的:

Row      Field1          Field2
 1         0               1
 2         ?               2
 3         ?               -5

我需要一个会逐行抛出的查询。 它应该取 row2,field1 并将其设置为等于 row1,field1+row2,field2

然后将 row3,field1 设置为等于 row2,field1+row3,field2

最初,该表在 Field1 中的值都等于 0,因此当我运行查询时,它总是将 0 用于 field1 值。

任何帮助将不胜感激。我在想 CTE 将是要走的路,但我只是不知道该去哪里。

编辑: 只是为了澄清一些事情,在我的例子中。初始输入是

Row      Field1          Field2
 1         0               1
 2         0               2
 3         0               -5

期望的输出是:

Row      Field1          Field2
 1         1               1
 2         3               2
 3         -2               -5 

我的实际表格有点复杂,但我知道我可以专门应用它,如果我能理解如何通过这个示例完成它。

【问题讨论】:

  • 显示的表格是您的输入吗?如果是,您也可以向我们展示您的预期结果吗?
  • 那么,您基本上是在寻找像this 这样的运行总数,但有点奇怪?我建议不要以这种方式在整个表上使用递归 CTE,因为它会涉及与行数一样多的索引/表扫描。
  • 如果您提供示例数据和所需的结果会更清楚。
  • 我进行了编辑以显示一些示例输入/输出。这有点像运行总计,但它只添加上一行和当前行的内容。实际数据集相当大(MLB play by play data)
  • @AnthonyTyler - 但是,如果它只是从前一行添加东西,而前一行中添加的字段又从前一行更新,那么它完全不是一个运行总计它?我没有看到您想要的结果与我的回答中第一种方法的结果有任何区别。也许更新您的示例以显示差异?

标签: sql sql-server-2012


【解决方案1】:

这是你需要的吗? (不清楚当您引用 row2,field1 时,您的意思是更新前还是更新后的值)

CREATE TABLE YourTable
  (
     Row    INT,
     Field1 INT NULL,
     Field2 INT
  )

INSERT INTO YourTable
VALUES      (1,0,1),
            (2,0,2),
            (3,0,-5); 
WITH CTE AS
(
SELECT *,
       SUM(Field2) OVER (ORDER BY Row ROWS UNBOUNDED PRECEDING) AS RunningTotal
FROM  YourTable    
)
UPDATE CTE 
SET Field1 = RunningTotal

SELECT *
FROM YourTable

最终结果

Row         Field1      Field2
----------- ----------- -----------
1           1           1
2           3           2
3           -2          -5

或者你的单词问题的另一种(更字面的)解释可能是

WITH CTE AS
(
SELECT *,
       LAG(Field2) OVER (ORDER BY Row) AS PrevRowField2
FROM  YourTable    
)
UPDATE CTE 
SET Field1 = PrevRowField2 + Field1
WHERE PrevRowField2 IS NOT NULL

【讨论】:

  • 想知道您是如何得出 OP 想要的结果的吗? Coz Field 1 在 OP 的问题中没有任何值 :)
  • 问题文本说它们都是零。声称我已经找到了他们想要的结果可能还为时过早(!),但它提供了一个起点。
  • 这比我的答案更有效,如果我得到正确的结果集,也很容易适应。我没有将其视为第 1 行字段 1 正在更新,这很可能是需要的。
  • @Laurence - 我试图在字里行间读懂 OP 的实际用途。不幸的是,OP似乎已经离开而不是坚持澄清。我同意你的回答,虽然他们从未提到更新row1,field1 (+1),但我认为这可能是一个疏忽。
  • 处理第 2 行,更改第 1 字段,然后使用第 2 行字段 1 中的新值处理第 3 行。
【解决方案2】:

类似这样的东西改编自TSQL A recursive update?

With cte As (
  Select
    Row, 
    Field1, 
    Field2
  From
    t
  Where
    Row = 1
  Union All
  Select
    t.Row,
    t.Field2 + c.Field1,
    t.Field2
  From
    t
      Inner Join
    cte c
      On t.Row = c.Row + 1
)
Update
  t
Set
  Field1 = c.Field1
From
  t
    inner join
  cte c
    On t.Row = c.Row

http://sqlfiddle.com/#!6/cf843/1

【讨论】:

    猜你喜欢
    • 2013-11-18
    • 2023-03-22
    • 1970-01-01
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-03
    相关资源
    最近更新 更多