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