0

次のようなテーブルがあります。

| prodID  | date     |  perm
---------------------------------   
|200      |8/7/2011  | 81.742 
|200      |8/7/2011  | 81.644
|200      |8/7/2011  | 81.302
|200      |8/7/2011  | 81.057
|201      |8/7/2011  | 80.932
|201      |8/7/2011  | 80.839
|201      |8/7/2011  | 80.622
|201      |8/7/2011  | 80.557
|201      |8/7/2011  | 80.541

(少し大きいものを除く) 何が起こるかの内訳: prodid = somevalue (この場合は 200) である上位 10 個の値 (および下位 10 個の値) の平均を取得したいと考えています。

コード:

declare @myid int
set @myid = 200

;with high as  --top ten average
(
 select prodid, CONVERT(CHAR(10),  DATEADD(DAY, AVG(DATEDIFF(DAY, 0, CONVERT    
(SMALLDATETIME, [date]))), 0),     101) as date, max(perm)as max_perm, avg(perm) 
as   
high_perm from   
( select prodid, date, perm, 
 row_number() over(partition by date order by perm desc) as nt    
 from live_pilot_plant
 where prodid = @myid) as T 
 where nt <= 10
 group by prodid
),
low as   -- bottom ten average
(
select prodid, CONVERT(CHAR(10),  DATEADD(DAY, AVG(DATEDIFF(DAY, 0, CONVERT    
(SMALLDATETIME, [date]))), 0),101) as date, min(perm) as min_perm, avg(perm) 
as low_perm  from   
( select prodid, date, perm,  
  row_number() over(partition by date order by perm asc) as nt    
  from live_pilot_plant
  where prodid = @myid) as T 
  where nt <= 10
  group by prodid
)

select l.prodid, l.date, l.low_perm as low_avg, m.high_perm as high_avg,
(m.high_perm -    l.low_perm) as delta
from low l
left outer join high m
on l.prodid = m.prodid 

次のようなものが生成されます。

|  prodID  |   date     |  low_avg   |  high_avg  |  delta   |
|   200    | 08/07/2011 |   68.752   |  79.1976   |  10.444  |

これらの数値は正確ではありません --

これは、非常に汎用性がないことを除いて、すべて良いとダンディです. つまり、多くの prodID があり、prodID に基づいてこれを行うには遅すぎます。日付に基づいて low_avg と high_avg を取得するにはどうすればよいですか (prodID でグループ化)

このようなもの:

| date       | prodID  | low_avg  | high_avg  |  delta  |
| 08/07/2011 | 200     |  60      |  80       |  20     |
| 08/07/2011 | 201     |  70      |  100      | 100     |

注: date の前にクレイジーな変換があることに気付いたかもしれません。その理由は、一部の prodID の日付が重複しているためです。2011 年 8 月 7 日と 2011 年 8 月 8 日に 200 であり、日付 (varchar) を平均化する必要があります。たとえば、2011 年 8 月 7 日の行が 100 行あり、2011 年 8 月 8 日の行が 9 行ある場合、最終的なクエリは /8/7/2011 という日付を生成します。

4

1 に答える 1

1

次のクエリは、すべての製品に対して一度に実行します。

select lpp.prod_id, lpp.date,
       AVG(case when seqnum_asc <= 10 then perm end) as avg_bottom10,
       AVG(case when seqnum_desc <= 10 then perm end) as avg_top10,
       (AVG(case when seqnum_desc <= 10 then perm end) - AVG(case when seqnum_asc <= 10 then perm end)) as delta
from (select lpp.*,
             ROW_NUMBER() over (partition by prodid, date order by perm) as seqnum_asc,
             ROW_NUMBER() over (partition by prodid, date order by perm desc) as seqnum_desc
      from live_pilot_plan lpp
     ) lpp
group by lpp.prod_id, lpp.ate
于 2012-07-18T19:52:16.153 に答える