システムが毎月メーターを読み取るメーター システムのカーソルの例が必要です。
カーソルは、すべてのメーターに現在の年に登録された測定値があることを確認する必要があります。測定値が欠落しているメーターについては、1 日あたりの消費量が前の期間の 1 日あたりの消費量に 15% を加えたものになるように、推定値が追加されます。前の期間が存在しない場合は、上記の Kwh の値が使用されます。
システムが毎月メーターを読み取るメーター システムのカーソルの例が必要です。
カーソルは、すべてのメーターに現在の年に登録された測定値があることを確認する必要があります。測定値が欠落しているメーターについては、1 日あたりの消費量が前の期間の 1 日あたりの消費量に 15% を加えたものになるように、推定値が追加されます。前の期間が存在しない場合は、上記の Kwh の値が使用されます。
このようなものはどうですか。(MonthSeed テーブルは、データベース内の実際のテーブルになる可能性があります)
declare @MonthSeed table (MonthNumber int)
insert into @MonthSeed values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
-- assumes declared table "Reading" with fields ( Id int, [Date] datetime, MeterNo varchar(50), Consumption int )
select
m.MeterNo,
r.Date,
calculatedConsumption = isnull(r.Consumption, -- read consumption
isnull((select max(r2.Consumption) Consumption from Reading r2 where datepart(month, r2.Date) = (m.MonthNumber - 1) and r2.MeterNo = m.MeterNo) * 1.15, -- previous consumption + 15%
9999)) -- default consumption
from
(select distinct
MeterNo,
MonthNumber
from
Reading, @MonthSeed) m
left join
Reading r on r.MeterNo = m.MeterNo and datepart(month, r.Date) = m.monthNumber
以下のコメントを編集 - 欠落している読みを追加する例
コメントされているように、選択の前に挿入を含める必要があり、テーブルinsert into Reading (MeterNo, Date, Consumption)
への左結合を利用するにはreading
、読み取りIDがnullであること、つまりmissingであることのチェックが含まれますwhere r.Id is null
。
reading
これにより、テーブルに挿入するときに日付エントリが null になることに気付きました。そのため、メインの sub-select に日付集計を含めましたDate = dateadd(month, monthnumber, @seeddate)
。メインの選択項目が修正され、欠落しているエントリの日付が表示されるようになりましたisnull(r.Date, m.Date),
@SeedDate
を1 年前の当月 1 日と計算しましたが、もっと早い日付を渡すことをお勧めします。
declare @MonthSeed table (MonthNumber int)
insert into @MonthSeed values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)
-- assumes declared table "Reading" with fields ( Id int, [Date] datetime, MeterNo varchar(50), Consumption int )
declare @SeedDate datetime = (select dateadd(month, datediff(month, 0, getdate())-12, 0)) -- this month, last year
insert into Reading (MeterNo, Date, Consumption)
select
m.MeterNo,
isnull(r.Date, m.Date),
calculatedConsumption =
isnull(r.Consumption, -- read consumption
isnull(1.15 * (select max(r2.Consumption) Consumption
from Reading r2
where datepart(month, r2.Date) = (m.MonthNumber - 1)
and r2.MeterNo = m.MeterNo), -- previous consumption + 15%
9999)) -- default consumption
from
(select distinct
MeterNo,
MonthNumber,
Date = dateadd(month, monthnumber, @seeddate)
from
Reading
cross join
@MonthSeed) m
left join
Reading r on r.MeterNo = m.MeterNo and datepart(month, r.Date) = m.monthNumber
where
r.Id is null
select * from Reading
(以下は SQL Server 2005 以降を想定しています。)
ここを探し回って、価値のあるものがないか見てみましょう:
declare @StartDate as Date = '2012-01-01'
declare @Now as Date = GetDate()
declare @DefaultConsumption as Int = 2000 -- KWh.
declare @MeterReadings as Table
( MeterReadingId Int Identity, ReadingDate Date, MeterNumber VarChar(10), Consumption Int )
insert into @MeterReadings ( ReadingDate, MeterNumber, Consumption ) values
( '2012-01-13', 'E154', 2710 ),
( '2012-01-19', 'BR549', 650 ),
( '2012-02-15', 'E154', 2970 ),
( '2012-02-19', 'BR549', 618 ),
( '2012-03-16', 'BR549', 758 ),
( '2012-04-11', 'E154', 2633 ),
( '2012-04-20', 'BR549', 691 )
; with Months ( Month ) as (
select @StartDate as [Month]
union all
select DateAdd( mm, 1, Month )
from Months
where Month < @Now
),
MeterNumbers ( MeterNumber ) as (
select distinct MeterNumber
from @MeterReadings )
select M.Month, MN.MeterNumber,
MR.MeterReadingId, MR.ReadingDate, MR.Consumption,
Coalesce( MR.Consumption, @DefaultConsumption ) as [BillableConsumption],
( select Max( ReadingDate ) from @MeterReadings where MeterNumber = MN.MeterNumber and ReadingDate < M.Month ) as [PriorReadingDate],
( select Consumption from @MeterReadings where MeterNumber = MN.MeterNumber and ReadingDate =
( select Max( ReadingDate ) from @MeterReadings where MeterNumber = MN.MeterNumber and ReadingDate < M.Month ) ) as [PriorConsumption],
( select Consumption from @MeterReadings where MeterNumber = MN.MeterNumber and ReadingDate =
( select Max( ReadingDate ) from @MeterReadings where MeterNumber = MN.MeterNumber and ReadingDate < M.Month ) ) * 1.15 as [PriorConsumptionPlus15Percent]
from Months as M cross join
MeterNumbers as MN left outer join
@MeterReadings as MR on MR.MeterNumber = MN.MeterNumber and DateAdd( dd, 1 - DatePart( dd, MR.ReadingDate ), MR.ReadingDate ) = M.Month
order by M.Month, MN.MeterNumber