我有CRM项目,负责维护每个组织的产品销售订单。
我想计算每天售出的股票,我已经设法按日期循环,但显然这是一种荒谬的方法,并且需要更多的时间和记忆。
请帮我在单个查询中找到它。有可能吗?
这是我的数据库结构供您参考。
产品:id(PK),名称
组织:id(PK),名称
sales_order :ID(PK),product_id(FK),organization_id(FK),sold_stock,sold_date(纪元时间)
所选月份的预期输出:
organization | product | day1_sold_stock | day2_sold_stock | ..... | day30_sold_stock
答案 0 :(得分:2)
创建tablfunc:
CREATE EXTENSION IF NOT EXISTS tablefunc;
查询:
select "proId" as ProductId ,product_name as ProductName,organizationName as OrganizationName,
coalesce( "1-day",0) as "1-day" ,coalesce( "2-day",0) as "2-day" ,coalesce( "3-day",0) as "3-day" ,
coalesce( "4-day",0) as "4-day" ,coalesce( "5-day",0) as "5-day" ,coalesce( "6-day",0) as "6-day" ,
coalesce( "7-day",0) as "7-day" ,coalesce( "8-day",0) as "8-day" ,coalesce( "9-day",0) as "9-day" ,
coalesce("10-day",0) as "10-day" ,coalesce("11-day",0) as "11-day" ,coalesce("12-day",0) as "12-day" ,
coalesce("13-day",0) as "13-day" ,coalesce("14-day",0) as "14-day" ,coalesce("15-day",0) as"15-day" ,
coalesce("16-day",0) as "16-day" ,coalesce("17-day",0) as "17-day" ,coalesce("18-day",0) as "18-day" ,
coalesce("19-day",0) as "19-day" ,coalesce("20-day",0) as "20-day" ,coalesce("21-day",0) as"21-day" ,
coalesce("22-day",0) as "22-day" ,coalesce("23-day",0) as "23-day" ,coalesce("24-day",0) as "24-day" ,
coalesce("25-day",0) as "25-day" ,coalesce("26-day",0) as "26-day" ,coalesce("27-day",0) as"27-day" ,
coalesce("28-day",0) as "28-day" ,coalesce("29-day",0) as "29-day" ,coalesce("30-day",0) as "30-day" ,
coalesce("31-day",0) as"31-day"
from crosstab(
'select hist.product_id,pr.name,o.name,EXTRACT(day FROM TO_TIMESTAMP(hist.sold_date/1000)),sum(sold_stock)
from sales_order hist
left join product pr on pr.id = hist.product_id
left join organization o on o.id = hist.organization_id
where EXTRACT(MONTH FROM TO_TIMESTAMP(hist.sold_date/1000)) =5
and EXTRACT(YEAR FROM TO_TIMESTAMP(hist.sold_date/1000)) = 2017
group by hist.product_id,pr.name,EXTRACT(day FROM TO_TIMESTAMP(hist.sold_date/1000)),o.name
order by o.name,pr.name',
'select d from generate_series(1,31) d')
as ("proId" int ,product_name text,organizationName text,
"1-day" float,"2-day" float,"3-day" float,"4-day" float,"5-day" float,"6-day" float
,"7-day" float,"8-day" float,"9-day" float,"10-day" float,"11-day" float,"12-day" float,"13-day" float,"14-day" float,"15-day" float,"16-day" float,"17-day" float
,"18-day" float,"19-day" float,"20-day" float,"21-day" float,"22-day" float,"23-day" float,"24-day" float,"25-day" float,"26-day" float,"27-day" float,"28-day" float,
"29-day" float,"30-day" float,"31-day" float);
请注意,使用PostgreSQL Crosstab查询。我使用coalesce来处理空值(交叉表查询显示" 0"当有空数据返回时)。
答案 1 :(得分:1)
以下查询将有助于找到相同的内容:
select o.name,
p.name,
sum(case when extract (day from to_timestamp(sold_date))=1 then sold_stock else 0 end)day1_sold_stock,
sum(case when extract (day from to_timestamp(sold_date))=2 then sold_stock else 0 end)day2_sold_stock,
sum(case when extract (day from to_timestamp(sold_date))=3 then sold_stock else 0 end)day3_sold_stock,
from sales_order so,
organization o,
product p
where so.organization_id=o.id
and so.product_id=p.id
group by o.name,
p.name;
我只提供了3天的逻辑,你可以在剩下的时间里实现相同的目标。
基本上首先对id进行基本连接,然后检查每个日期(在将epoch转换为时间戳然后提取日期之后)。
答案 2 :(得分:1)
这里有几个选项,但首先要了解这些限制很重要。
最大的限制是规划人员需要在规划阶段之前知道记录大小,因此必须明确定义,而不是动态定义。有各种方法来解决这个问题。在一天结束的时候,你可能会像Bavesh的回答一样,但有一些工具可能会有所帮助。
其次,您可能希望在加入三个表然后转动的简单查询中按日期汇总。
对于第二种方法,您可以:
然后我们遇到第一个问题,即如果你总是做30天,那么如果你很乏味则很容易。但是,如果你想每天做一个月,你会遇到行长问题。在这里你可以做的是在函数(pl / pgsql)中创建一个动态查询并返回一个refcursor。在这种情况下,实际计划发生在功能中,计划员不需要在外层担心。然后在输出上调用FETCH
。