2016-11-28 9 views
3

私は車が彼のタンクがいっぱいになるたびに私を示す次の表があります。それは、日付、車のID、それはその時点で持っていた走行距離と埋めリットルを返します。2列で最大と最小のグループ

| Date  | Vehicle_ID | Mileage | Liters | 
| 2016-10-20 | 234  | 123456 | 100 | 
| 2016-10-20 | 345  | 458456 | 215 | 
| 2016-10-20 | 323  | 756456 | 265 | 
| 2016-10-25 | 234  | 123800 | 32  | 
| 2016-10-26 | 345  | 459000 | 15  | 
| 2016-10-26 | 323  | 756796 | 46  | 

アイデアは月ごとに平均comsumptionを計算することである(私は一日でそれを行うことはできませんので、必ずしもすべての車は毎日タンクを満たします)。

これを得るには、月ごとにmax(mileage) - min(mileage)/ sum(liters)を取得しようとしました。しかし、これは1台の特定の車と1ヶ月にのみ有効です。

私が1台の特定の車と数ヶ月を試してみると、最大値と最小値は正しく返されません。すべての車を追加すると、さらに悪いことに、すべての車が同じであるかのように最大値と最小値を仮定します。

select convert(char(7), Date, 127) as year_month, 
     sum("Liters tanked")/(max("Mileage")-min("Mileage"))*100 as Litres_per_100KM 
from Tanking 
where convert(varchar(10),"Date",23) >= DATEADD(mm, -5, GETDATE()) 
group by convert(char(7), Date, 127) 

これは、すべての車の最大値と最小値を想定しているため動作しません。

「ワークフロー」は、次のようになります。 - 毎月、各車の最大および最小のマイルを取得します。その月に乗った走行距離を得るためにmax-minを計算します。各自動車の走行距離を合計して、すべての自動車が走行する総走行距離を取得します。リットルをタンクに入れてください。総リットルを総走行距離で割る。

にはどうすればいい結果を得ることができます。

| YearMonth | Average | 
| 2016-06 | 30  | 
| 2016-07 | 32  | 
| 2016-08 | 46  | 
| 2016-09 | 34  | 
+0

「私がいないすべての車の塗りつぶしので、日によってそれを行うことはできません毎日タンク "。毎月の消費量を約30で割ったものではありませんか? – Strawberry

+0

こんにちはストロベリー。いいえ、私が「日ごとの平均」を望むなら、それはそのように機能します。しかし、私が毎日何を意味するかは、 "1日目 - 平均X"、 "2日目 - 平均Y"などでした。 –

+0

出力には、 '2016-09'、' 2016-08'、 '2016-07' 「2016-06」。しかし、サンプルデータにはこれらの月の記録は含まれていません。更新することができますので、私たちは何か対処する必要があります。 –

答えて

1

これは、より複雑な問題です。問題は、数か月間にマイルを失いたくないということです。それはこのような何かをすることは魅力的である:

select year(date), month(date), 
     sum(liters)/(max(mileage) - min(mileage)) 
from Tanking 
where Date >= dateadd(month, -5, getdate()) 
group by year(date), month(date); 

しかし、これはスパン月境界というマイルリットルをミス。さらに、今月の最初のレコードのリットルは、の前のの差です。おっとっと!それは正しくありません。

これを修正する1つの方法は、次の値を検索することです。クエリは次のようになります。

select year(date), month(date), 
     sum(next_liters)/(max(next_mileage) - min(mileage)) 
from (select t.*, 
      lead(date) over (partition by vehicle_id order by date) as next_date, 
      lead(mileage) over (partition by vehicle_id order by date) as next_mileage, 
      lead(liters) over (partition by vehicle_id order by date) as next_liters 
     from Tanking t 
    ) t 
where Date >= dateadd(month, -5, getdate()) 
group by year(date), month(date); 

これらのクエリは簡略化された列名を使用するため、エスケープ文字はロジックに干渉しません。

EDIT:

ああ、あなたが複数の車を持っている(おそらく何vehicle_Idのためにそこにあります)。 2つのレベルの集計が必要です。 (partition by節でvehicle_id付き)2番目のクエリと同様の変化が第二バージョンのために働くだろう

select yyyy, mm, sum(liters) as liters, sum(mileage_diff) as mileage_diff, 
     sum(mileage_diff)/sum(liters) as mileage_per_liter 
from (select vehicle_id, year(date) as yyyy, month(date) as mm, 
      sum(liters) as liters, 
      (max(mileage) - min(mileage)) as mileage_diff 
     from Tanking 
     where Date >= dateadd(month, -5, getdate()) 
     group by vehicle_year(date), month(date) 
    ) t 
group by yyyy, mm; 

:最初のクエリは次のようになります。

+0

答えに感謝します。私たちは近似を望んでいると考えています(数ヶ月にわたる走行距離とリットルを理解することは不可能です)。 30台の車があると想像しているので、最初のクエリは機能しません。最高走行距離は、走行距離計で500kマイルを有する自動車1からのものであってもよく、10マイルを有する自動車21からのものであってもよい。今月中にすべての車が10マイルしか走行しなかったとしても、総走行距離は300マイルになるはずです。しかし、最大(マイレージ) - 分(マイレージ)は500k - 10マイルを返します。それは私の問題です - どのように私は各車の最大と最小の差を取得し、それらを合計することができます。 –

+0

ありがとうございました!それは動作します! –

0

は、サブクエリで月額車あたりの合計を取得してください。次に、サブクエリの値を使用して外側のクエリで1か月あたりの平均を計算します。

select year_month, 
     (1.0*sum(liters_per_car)/sum(mileage_per_car))*100.0 as Litres_per_100KM 
from (
    select convert(char(7), [Date], 127) as year_month,  
      sum(Liters) as liters_per_car, 
      max(Mileage)-min(Mileage) as mileage_per_car  
    from Tanking 
    group by convert(char(7), [Date], 127), Vehicle_ID) as t 
group by year_month 
0

あなたはDIF(走行距離)を取得し、消費量を計算するためにCTEを使用することができます。

は、ここでそれを確認することができます:http://rextester.com/OKZO55169

with cte (car, datec, difm, liters) 
as 
(
select 
    car, 
    datec, 
    mileage - lag(mileage,1,mileage) over(partition by car order by car, mileage) as difm, 
    liters 
from #consum 
) 
select 
    car, 
    year(datec) as [year], 
    month(datec) as [month], 
    ((cast(sum(liters) as float)/cast(sum(difm) as float)) * 100.0) as [l_100km] 
from 
    cte 
group by 
    car, year(datec), month(datec) 
+0

ありがとうございました!それも同様に動作します! –

関連する問題