0

私の問題は次のとおりです。

  1. selectの値の 1 つ ( average ) が nullかどうかを確認する必要があります
  2. そうである場合は、選択を実行して、異なる期間 (日付) の最初の非 null 値を探します。
  3. この後、これが(日付-範囲)のどの期間であるかを確認する操作を実行します。
  4. その後、平均を行います

人間の言語

期間ごとにグループ化されたすべての製品の平均コストを取得したい。

特定の期間に製品に請求書がない場合、前の期間の平均を取得する必要があります (平均コストがある場合)。

期間は月ではなく、顧客によって定義され、2 か月をオーバーラップできます。次に例を示します。

2012-01-01 - 2012-01-29
2012-01-30 - 2012-02-27

1つのクエリでこれを行うにはどうすればよいですか?
クエリは多かれ少なかれ次のようになります (average値を比較したい列です):

select
    p.id
    ,(select 
        avg(cost)
    from 
        invoices i 
    where 
        i.product_id = p.id 
        and i.add_date between $start_date
        and $end_date
    ) as average
from
    products p;

テーブル/データ/クエリ

この要点を参照してください (元のデータベースではありません。今このテストを行います): https://gist.github.com/4520123

4

3 に答える 3

1

あなたの問題を解決する他の方法は次のとおりです。

  1. データが利用可能な最新の月を見つけます。
  2. ステップ 1 から月の avg() を取得します。

クエリ:

SELECT i.product_id, 
       max(date_trunc('month',i.add_date)) as last_month
FROM invoices i 
GROUP BY i.product_id

すべての製品で利用可能なデータを先月提供します。

それで:

SELECT p.id,
       avg(inv.cost)
FROM products p
JOIN invoices inv 
  ON inv.product_id = p.id
JOIN (SELECT i.product_id, 
             max(date_trunc('month',i.add_date)) as last_month
      FROM invoices i 
      GROUP BY i.product_id) last_inv 
  ON last_inv.product_id = inv.product_id
  AND last_inv.last_month = date_trunc('month',inv.add_date)

avg先月のを取得します。

于 2013-01-11T22:50:20.570 に答える
0

私はそれを手に入れたと思います。異なる期間の平均を連続してチェックしたいと考えています。以下は、3 つの期間の例です。

select p.id,
       coalesce(cost_period1, cost_period2, cost_period3) as average
from products p left outer join
     (select i.product_id, 
             avg(case when i.add_date between $start_date1 and $end_date1 then cost
                 end) as cost_period1,
             avg(case when i.add_date between $start_date2 and $end_date2 then cost
                 end) as cost_period2,
             avg(case when i.add_date between $start_date3 and $end_date3 then cost
                 end) as cost_period3
      from invoices i
      group by i.product_id
     ) ip
     on p.id = ip.product_id

これはテストされていないクエリです。サブクエリの各期間の平均が計算され、最初の非 NULL 値が選択されます。

あなたのコメントに基づいて、これを月ごとに別の行に変換するだけです。これが典型的な方法です。. . 年と月でグループ化し、利用可能な最新のものを選択します。

select p.id, avgcost
from products p left outer join
     (select ip.*, row_number() over (partition by product_id order by yearmon desc) as seqnum
      from (select i.product_id, year(add_date)*12+month(add_date) as yearmon,
                   avg(cost) as avgcost
            from invoices i
            group by i.product_id, year(add_date)*12+month(add_date)
           ) ip
      where seqnum = 1
     ) ip
     on p.id = ip.product_id
于 2013-01-11T20:34:10.673 に答える
0

同僚の助けを借りて、このクエリを使用して質問を解決します。

私がしたことは、最後の購入(請求書)、特定の製品(飲み物)を取り、平均を計算することでした.

    select (sum(aux.price * aux.quantity) / sum(aux.quantity))
    from (select    inp.price, inp.quantity, prd.product, drk.drink_num, inv.add_date
                        from    invoices                                inv
            inner join invoice_products inp on inp.invoice = inv.invoice
            inner join products                 prd on prd.product = inp.product
            inner join drinks                       drk on drk.product = prd.product) aux,
    date_period dtp
    where 
            aux.add_date between dtp.starting_date and dtp.ending_date
            and aux.drink_num = 1836 -- example id
            and dtp.year <= 2012 -- current year search
    group by
            dtp.year,
            dtp.period
    order by 
            dtp.year desc,
            dtp.period desc
    limit 1

とにかく、みんなありがとう!

于 2013-01-12T13:24:21.200 に答える