SQL Server 2008 - 需要有关对立查询的帮助

时间:2014-11-04 03:34:39

标签: sql sql-server-2008 tsql sql-server-2008-r2

我想知道给定交易日的抄表。在某些情况下,不会有任何抄表,并希望看到前一天的抄表。

示例数据集如下。我正在使用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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

我可以想到两种方法来解决这个问题 - 它们都不是理想的。

第一种(稍微好一点)的方法是创建一个SQL函数,它将Transactions_date作为参数并返回Max(Reading_date)的读数,其中reading_date< = transactions_date。然后,您可以在针对Transactions表的select语句中使用此函数。

另一种方法是使用游标迭代事务表,并使用与上面相同的逻辑,返回Max(Reading_date)的读数,其中reading_date< = transactions_date。

答案 2 :(得分: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