0

我的问题如下:

  1. 我需要检查一个选择的值(平均值)是否为空
  2. 如果是,请运行选择以查找不同时期(日期)中的第一个非空值。
  3. 在此之后,执行一个操作来检查(日期 - 范围)是什么时间段,这是
  4. 之后做平均

人类语言

我想得到所有产品的平均成本按期间分组

如果在特定期间,产品没有发票,我需要获取上一期间的平均值(如果有平均成本)。

期间不是几个月,它们由客户定义,可以重叠 2 个月,例如:

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

我怎样才能在一个查询中做到这一点?
查询或多或少如下(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. 从第一步获取当月的 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

我想我明白了。您想连续检查不同时期的平均值。以下是三个时期的示例:

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 回答