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

Sql 查找同一表中两个字段之间的差异,sql,sql-server,database,tsql,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) 使用者id是引用使用者详细信息表的外键 我想要的是从上个月的读数中减去每个客户当前的读数。这将生成

我有一个表,其中存储每月帐单信息

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)
使用者id是引用使用者详细信息表的外键


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

您可以使用类似的方法,替换要返回的月份/年份的值:

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;

如果您不想输入要搜索的
月份
年份
的值,并且您只想要当前/上一个月,那么您可以使用类似于以下内容的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

此版本获取要使用的当前/上个月和年份值。如果您不熟悉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;


正如您在我的查询中所看到的,我在
消费者id
上使用了聚合函数
SUM()
分组依据。如果每个客户都有不止一个读数,我就这么做了。如果您知道每个月只有一个读数,那么您可以删除该聚合

您可以使用类似的方法,替换要返回的月份/年份的值:

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;

如果您不想输入要搜索的
月份
年份
的值,并且您只想要当前/上一个月,那么您可以使用类似于以下内容的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

此版本获取要使用的当前/上个月和年份值。如果您不熟悉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;


正如您在我的查询中所看到的,我在
消费者id
上使用了聚合函数
SUM()
分组依据。如果每个客户都有不止一个读数,我就这么做了。如果您知道每个月只有一个读数,那么您可以删除该聚合

sql server的哪个版本?
上个月的读数
:每个客户每月的账单历史记录中只有一个条目?是,每个客户每月只有一个条目。sql server的哪个版本?
上个月的读数
:每个客户每月的账单历史记录中只有一个条目客户?是的,每个月每个客户只有一个条目。我有另一个表格,其中有商业/国内消费者的消费数量。例如,50台*4用于家庭消费者,10用于商业消费者。如何将这些值乘以对上述查询的结果读取。@ USE2018566:如果这是不能应用这个答案的东西,那么你应该考虑考虑一个新问题。我们倾向于在这个网站上保持简单:一个问题,一个问题。@user2018756如果您不能添加其他表,那么我建议您在使用的查询中再问一个问题,然后再问新的详细信息。这将是获得帮助的最简单方式。:)我还有一张桌子,上面有一块板,是为商业/国内消费者提供的,用于计算消费的单位数量。例如,50台*4用于家庭消费者,10用于商业消费者。如何将这些值乘以对上述查询的结果读取。@ USE2018566:如果这是不能应用这个答案的东西,那么你应该考虑考虑一个新问题。我们倾向于在这个网站上保持简单:一个问题,一个问题。@user2018756如果您不能添加其他表,那么我建议您在使用的查询中再问一个问题,然后再问新的详细信息。这将是获得帮助的最简单方式。:)