2014-11-04 3 views
0

Я хочу найти показания счетчика для данного дня транзакции. В некоторых случаях не будет никакого показания счетчика и хотелось бы видеть показания счетчика за предыдущий день.SQL Server 2008 - нужна помощь по противоположным запросам

Ниже приведен пример набора данных. Я использую SQL Server 2008

declare @meter table (UnitID int, reading_Date date,reading int) 
declare @Transactions table (Transactions_ID int,UnitID int,Transactions_date date) 


insert into @meter (UnitID,reading_Date,reading) values 
(1,'1/1/2014',1000), 
(1,'2/1/2014',1010), 
(1,'3/1/2014',1020), 
(2,'1/1/2014',1001), 
(3,'1/1/2014',1002); 

insert into @Transactions(Transactions_ID,UnitID,Transactions_date) values 
(1,1,'1/1/2014'), 
(2,1,'2/1/2014'), 
(3,1,'3/1/2014'), 
(4,1,'4/1/2014'), 
(5,2,'1/1/2014'), 
(6,2,'3/1/2014'), 
(7,3,'4/1/2014'); 

select * from @meter; 
select * from @Transactions; 

Я ожидаю, чтобы получить следующий вывод

Transactions 
Transactions_ID  UnitID Transactions_date reading 
1     1  1/1/2014   1000 
2     1  2/1/2014   1010 
3     1  3/1/2014   1020 
4     1  4/1/2014   1020 
5     2  1/1/2014   1001 
6     2  3/1/2014   1001 
7     3  4/1/2014   1002 
+1

Добавить, что вы пробовали до сих пор, а также желаемый результат, основанный на ваших данных образца. –

+1

Как вы определяете «* предыдущий день»? Что делать, если альтернативное чтение недоступно? –

+2

Вы хотите вывести каждое значение из транзакции и значение от счетчика, который является самым последним в или до транзакции_данных? –

ответ

2

Ваш SQL-запрос, чтобы получить желаемый вывод будет следующим:

SELECT Transactions_ID, T.UnitID, Transactions_date 
, (CASE WHEN ISNULL(M.reading,'') = '' THEN 
     (
      SELECT MAX(Reading) FROM @meter AS A 
      JOIN @Transactions AS B ON A.UnitID=B.UnitID AND A.UnitID=T.UnitID 
     ) 
    ELSE M.reading END) AS Reading 
FROM @meter AS M 
RIGHT OUTER JOIN @Transactions AS T ON T.UnitID=M.UnitID 
AND T.Transactions_date=M.reading_Date 
+0

Привет, Bhavesh, похоже, что выходы не совсем совпадают для последних двух транзакций – blksdw

+0

Привет, @blksdw, Спасибо, что больше внимания уделяю неправильному выходу, я просто исправлю это. могу проверить. –

+0

Я никогда не знал, что вы можете использовать оператор select в инструкции CASE. Ваш ответ был очень воспитательным для меня, спасибо. – SubqueryCrunch

0

я могу думать о двух способов приблизиться к этому - ни один из них не являются идеальными.

Первым (и немного лучшим) способом было бы создать SQL-функцию, которая взяла Transactions_date в качестве параметра и вернула чтение для Max (Reading_date), где read_date < = transaction_date. Затем вы можете использовать эту функцию в инструкции select в таблице «Транзакции».

Другим подходом было бы использовать курсор для итерации по таблице транзакций и использовать ту же логику, что и выше, где вы возвращаете показания для Max (Reading_date), где read_date < = transaction_date.

+0

Спасибо, greg. плохо попробуйте написать курсор и посмотреть – blksdw

+0

@blksdw На самом деле, я думаю, что ответ Бхавеша Харсоры, скорее всего, сработает - может потребоваться немного тонкой настройки, но это лучше, чем мое предложение. –

0

Попробуйте ниже запрос:

Пожалуйста найти результат тот же в SQLFiddle

select a.Transactions_ID, a.UnitID, a.Transactions_date, 
case when b.reading IS NULL then c.rd else b.reading end as reading 
from 
Transactions a 
left outer join 
meter b 
on a.UnitID = b.UnitID 
and a.Transactions_date = b.reading_Date 
inner join 
(
select UnitID,max(reading) as rd 
from meter 
group by UnitID 
) as C 
on a.UnitID = c.UnitID 
Смежные вопросы