找出同一个表中两个字段之间的差异

时间:2013-02-05 10:03:59

标签: sql sql-server database tsql

我有一个存储月度结算信息的表格。

CREATE TABLE [dbo].[billing_history](
[id] [numeric](18, 0) IDENTITY(1,1) NOT NULL,
[reading_date] [date] NOT NULL,
[reading] [numeric](18, 0) NOT NULL,
[consumer_id] [int] NOT NULL)

consumer_id是引用消费者详细信息表的外键。

我想要的是从上个月的读数中减去每个客户当前的读数。这将产生当前的账单。任何想法。

1 个答案:

答案 0 :(得分:4)

您可以使用与此类似的内容,您可以在其中替换要返回的月份/年份的值:

select b1.consumer_id,
  sum(b1.reading - isnull(b2.reading, 0)) Total
from billing_history b1
left join billing_history b2
  on b1.consumer_id = b2.consumer_id
  and month(b2.reading_date) =12
  and year(b2.reading_date) = 2012
where month(b1.reading_date) = 1
  and year(b1.reading_date) = 2013
group by b1.consumer_id;

请参阅SQL Fiddle with Demo

如果您不想传递monthyear的值进行搜索而您只想要当前/上个月,那么您可以使用CTE使用类似的内容:

;with cur as
(
  select consumer_id,
    reading,
    month(getdate()) curMonth,
    year(getdate()) curYear,
    case when month(getdate()) = 1 then 12 else month(getdate()) -1 end preMonth,
    case when month(getdate()) = 1 then year(getdate())-1 else year(getdate()) end preYear
  from billing_history
  where month(reading_date) = month(getdate())
    and year(reading_date) = year(getdate())
)
select c.consumer_id, 
  sum(c.reading - isnull(pre.reading, 0)) TotalReading
from cur c
left join billing_history pre
  on c.consumer_id = pre.consumer_id
  and month(pre.reading_date) = c.preMonth
  and year(pre.reading_date) = c.preYear
group by c.consumer_id

请参阅SQL Fiddle with Demo

此版本获取要使用的当前/上个月和年份值。如果您不熟悉CTE语法,也可以写成:

select c.consumer_id, 
  sum(c.reading - isnull(pre.reading, 0)) TotalReading
from
(
  select consumer_id,
    reading,
    month(getdate()) curMonth,
    year(getdate()) curYear,
    case when month(getdate()) = 1 then 12 else month(getdate()) -1 end preMonth,
    case when month(getdate()) = 1 then year(getdate())-1 else year(getdate()) end preYear
  from billing_history
  where month(reading_date) = month(getdate())
    and year(reading_date) = year(getdate())
) c
left join billing_history pre
  on c.consumer_id = pre.consumer_id
  and month(pre.reading_date) = c.preMonth
  and year(pre.reading_date) = c.preYear
group by c.consumer_id;

请参阅SQL Fiddle with Demo

正如您在我的查询中所看到的,我在SUM()上使用了聚合函数GROUP BYconsumer_id。如果每个客户有多个读数,我就这样做了。如果您知道每月只有一个阅读,那么您可以删除聚合。