Php 带条件的递归选择

Php 带条件的递归选择,php,sql,database,postgresql,Php,Sql,Database,Postgresql,我的问题如下: 我需要检查select的平均值之一是否为空 如果是,则运行select查找不同期间日期中的第一个非空值。 在此之后,执行一个操作来检查这是什么日期范围 之后做平均值 人类语言 我想得到所有产品的平均成本,按时段分组 如果在特定时期内,产品没有发票,我需要获得前一时期的平均值,如果这有一个平均成本 期间不是月,由客户定义,可以重叠2个月,例如: 2012-01-01 - 2012-01-29 2012-01-30 - 2012-02-27 如何在一个查询中完成此操作? 查询大致如

我的问题如下:

我需要检查select的平均值之一是否为空 如果是,则运行select查找不同期间日期中的第一个非空值。 在此之后,执行一个操作来检查这是什么日期范围 之后做平均值 人类语言 我想得到所有产品的平均成本,按时段分组

如果在特定时期内,产品没有发票,我需要获得前一时期的平均值,如果这有一个平均成本

期间不是月,由客户定义,可以重叠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;
表/数据/查询 看这个要点,不是原始数据库,我现在做这个测试:
我想我明白了。您希望连续检查不同时段的平均值。以下是三个时期的示例:

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
这是一个未经测试的查询。计算子查询中每个时段的平均值,然后选择第一个非空值

根据您的评论,您只需要在每个月将其转换为单独的一行。这是一个典型的方法。按年份和月份分组,然后选择最近可用的

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

解决问题的另一种方法是:

查找具有可用数据的最近月份。 从第一步中获取当月的平均值。 查询:

SELECT i.product_id, 
       max(date_trunc('month',i.add_date)) as last_month
FROM invoices i 
GROUP BY i.product_id
将为您提供每个产品的上个月可用数据

然后:


获取上个月的平均值。

在同事朋友的帮助下,我用这个查询解决了这个问题。 我所做的是,我拿了最后一张购买发票,具体的产品饮料,并计算了平均值


无论如何,谢谢你们

请写一个更能描述问题的标题。现在可以了吗?Postgre SQL查询中带条件的递归选择请提供示例数据和预期输出。你可能认为这个问题很清楚,但大多数阅读的人都不明白你想问什么。@GordonLinoff我现在编辑这篇文章。顺便说一句,当我们询问样本数据时,测试设置在左边,而不是不可能的查询在右边:我感谢你的帮助,但不是这样,因为我没有“exacly”期间的日期。我需要一个月接一个月地回来,直到找到结果。这是一个很好的解决办法。我试试看。但在我的例子中,更好的解决方案是在一个查询中完成所有查询。@PatrickMaciel您只需要运行第二个查询。它将第一个作为子查询。我写它只是为了解释它是如何工作的。@PatrickMaciel:你可以很容易地把它打包成一个查询。使用子选择或CTE。这是更好的解决方案,因为只计算相关的平均值。当我读到你的问题时,你的想法是,递归查询,计算平均值是不可能的@ErwinBrandstetter谢谢我的朋友。我将尝试遵循此解决方案和您的评论。再次感谢。
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)
    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