2013-08-07 3 views
0

Я работаю на 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 

Я хотел бы принимать значения от «БББ» строк и распространять их вверх (упорядочивание по дате) по существу делает:

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?

+0

Вы хотите обновить или просто выбрать? –

+0

Я хотел бы просто выбрать – Denis

+0

Я использую SQL Server 2008 R2 – Denis

ответ

2

Что-то довольно простой может быть

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

+0

Возможно ли это с LEFT JOIN? – Denis

+0

@Denis Я думаю, вам понадобится 'CROSS APPLY' – xanatos

+0

@Denis. Но то, что вы ищете, возможно, описано здесь: http://stackoverflow.com/questions/7045040/replace-null-values-with-latest-non -null-value-in-resultset-series-sql-server-2 – xanatos

1

Чтобы выбрать, вам может идти так же просто, как;

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.

Смежные вопросы