【问题标题】:Filling in missing data填写缺失数据
【发布时间】:2013-08-07 19:15:30
【问题描述】:

我在 SQL Server 中工作。假设我有下表:

3/1/2013    aaa   7     5
1/1/2013    bbb   1     2
10/10/2012  ccc   5     8
9/9/2012    ddd   6     9
8/8/2012    bbb   2     3

我想从“bbb”行中获取值并将它们向上传播(按日期排序)基本上是:

3/1/2013    aaa   1     2
1/1/2013    bbb   1     2
10/10/2012  ccc   2     3
9/9/2012    ddd   2     3
8/8/2012    bbb   2     3

在 SQL Server 中执行此操作的最佳方法是什么?

【问题讨论】:

  • 您要更新还是只选择?
  • 我只想选择
  • 我正在使用 SQL Server 2008 R2

标签: sql sql-server tsql


【解决方案1】:

一些非常基本的东西可能是

SELECT MT.Date, MT.Text, 
       CASE WHEN MT.Text = 'bbb' THEN Number
            ELSE (SELECT TOP 1 Number 
                               FROM MyTable MT2 
                               WHERE MT2.Date < MT.Date AND 
                                     MT2.Text = 'bbb'
                               ORDER BY MT2.Date DESC)
            END Number,
       CASE WHEN MT.Text = 'bbb' THEN Number2
            ELSE (SELECT TOP 1 Number2 
                               FROM MyTable MT2 
                               WHERE MT2.Date < MT.Date AND 
                                     MT2.Text = 'bbb'
                               ORDER BY MT2.Date DESC)
            END Number2 
       FROM MyTable MT

SQLFiddle:http://sqlfiddle.com/#!3/cbee5/3

或使用OUTER APPLY(应该更快)

SELECT MT.Date, MT.Text, 
       CASE WHEN MT.Text = 'bbb' THEN MT.Number
            ELSE MT2.Number 
            END Number,
       CASE WHEN MT.Text = 'bbb' THEN MT.Number2
            ELSE MT2.Number2
            END Number2
       FROM MyTable MT
       OUTER APPLY (SELECT TOP 1 MT2.Number, MT2.Number2 
                                 FROM MyTable MT2
                                 WHERE MT.Text <> 'bbb' AND 
                                       MT2.Text = 'bbb' AND 
                                       MT2.Date < MT.Date
                                 ORDER BY MT2.Date DESC
                   ) MT2

SQLFiddle:http://sqlfiddle.com/#!3/cbee5/7

【讨论】:

  • 左连接是否可行?
  • @Denis 我想你需要一个CROSS APPLY
  • @Denis 但是你要找的可能在这里描述:stackoverflow.com/questions/7045040/…
  • 我更新了我的问题以表明我的意思。我想我总是可以按照您建议的方式生成 2 列,但听起来效率不高。
  • @Denis 更改了 SELECT,现在有 more 列 :-)
【解决方案2】:

要选择,你可以这么简单;

SELECT t1.date, t1.tag, t2.val, t2.val2
FROM Table1 t1
JOIN Table1 t2 
  ON t2.tag='bbb' AND t1.date >= t2.date
LEFT JOIN Table1 t3 ON t3.tag = 'bbb' AND t1.date >= t3.date AND t3.date > t2.date
WHERE t3.date IS NULL

An SQLfiddle to test with.

更新表格的内容,您可以使用几乎相同的查询;

UPDATE t1
SET val=t2.val, val2=t2.val2
FROM Table1 t1
JOIN Table1 t2 
  ON t2.tag='bbb' AND t1.date >= t2.date
LEFT JOIN Table1 t3 ON t3.tag = 'bbb' AND t1.date >= t3.date AND t3.date > t2.date
WHERE t3.date IS NULL

Another SQLfiddle.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-02
    • 1970-01-01
    • 1970-01-01
    • 2014-03-21
    • 2020-05-12
    • 1970-01-01
    • 2019-08-01
    • 1970-01-01
    相关资源
    最近更新 更多