在一行中返回从现在起18个月的dated18值的sql查询

在一行中返回从现在起18个月的dated18值的sql查询,sql,oracle,oracle11g,Sql,Oracle,Oracle11g,我有一张12个周期(月)的表格,如下所述: CREATE TABLE "FORECAST_DATA" ( "COMPANY_CODE" NUMBER(6,0), "CAT" VARCHAR2(30), "PRODUCT_CODE" VARCHAR2(30), "CUSTOMER_CODE" VARCHAR2(30), "CYEAR" VARCHAR2(30), "CHANNEL" VARCHAR2(30), "P_1" NUMBER(6,0

我有一张12个周期(月)的表格,如下所述:

CREATE TABLE  "FORECAST_DATA" (
   "COMPANY_CODE" NUMBER(6,0), 
   "CAT" VARCHAR2(30), 
   "PRODUCT_CODE" VARCHAR2(30), 
   "CUSTOMER_CODE" VARCHAR2(30), 
   "CYEAR" VARCHAR2(30), 
   "CHANNEL" VARCHAR2(30), 
   "P_1" NUMBER(6,0), 
   "P_2" NUMBER(6,0), 
   "P_3" NUMBER(6,0), 
   "P_4" NUMBER(6,0), 
   "P_5" NUMBER(6,0), 
   "P_6" NUMBER(6,0), 
   "P_7" NUMBER(6,0), 
   "P_8" NUMBER(6,0), 
   "P_9" NUMBER(6,0), 
   "P_10" NUMBER(6,0), 
   "P_11" NUMBER(6,0), 
   "P_12" NUMBER(6,0), 
   "FORECAST_COST" NUMBER(6,0)
   )
此表用于预测,假设当前日期为2013年2月,我想编写一个查询,在一行中返回18个期间(2013年p_2到p_12,2014年p_1到p_7)

谢谢,


Sabe

使用
ADD_MONTHS
函数可以获得所需的列数。像这样的

SELECT sysdate, 
       ADD_MONTHS(sysdate,1) P_2,
       ADD_MONTHS(sysdate,2) P_3,
       ADD_MONTHS(sysdate,3) P_4,
       ADD_MONTHS(sysdate,4) P_5
FROM   dual;

感谢您提供的有用答案,但不是在本文中,P_1-P_12是带有数值的列名,我想返回这些数值。你的回答确实帮了我解决了我的其他问题。好吧,你对专栏有什么期待?当你说“返回18个周期”时,你期望的输出是什么。你能举个例子吗?很抱歉误解了,P_1包含特定产品在第1期(1月)的销售数量。感谢好消息,这是可行的(我以前做过,在一个13周期的零售日历中,周期1有时在8月,有时在9月)!坏消息是,它需要动态SQL!根据您的行数,您可以规范化数据库(获取
期间
列),然后使用列表聚合功能。
FORECAST\u COST
列是怎么回事?你预测全年的成本吗(我想波动性取决于商品)。是的,这是可行的,我确实使用了动态SQL,问题是响应时间,这就是为什么我在寻找用纯SQL实现的方法。FORECAST_COST是产品成本,是的,我预测全年的成本。另一个坏消息是动态SQL可能具有最好的性能,并且是最容易概念化/维护的。数据的一些基本统计数据是什么?行数、索引等?无论您如何编写查询,一个10亿行的表都会占用处理时间。并给我们一个动态查询的例子。Clockwork-Muse,我在下面发布了这个函数。你可以看一看,这应该是对你的问题的编辑,但我想我已经发现了一个潜在的问题:
WHERE
子句中的
CASE
语句可能会使任何索引的使用无效(并且可能会对每一行进行评估)。您的语句已经是动态的,只需去掉该条件-请注意,前导通配符(
%
)也将忽略索引。此查询似乎也引用了您问题中没有的列/表(好像它们可能是视图的一部分?)-这只是印刷上的差异,还是还有其他问题?谢谢发条缪斯,原始问题中引用的列/表是“印刷错误”。至于WHERE子句中的CASE语句,我将尝试消除它(CASE),但条件必须存在。我会在收到新信息后立即更新。
function after_current_date(p_months_before number,p_current_month number, p_year number, p_product_code varchar2, p_category varchar2, p_channel varchar2) return number
as
        v_qty number;
        v_quert_stmt  varchar2(4000);
begin

        v_quert_stmt := 'select sum(qty_'||case when p_current_month + p_months_before > 12 
                                                       then case when p_current_month + p_months_before > 24 then
                                                                      p_current_month + p_months_before - 24
                                                                 else p_current_month + p_months_before - 12
                                                            end     
                                                  else p_current_month + p_months_before 
                                             end 
                    ||') from forecast_data_1
                        where cyear        = :bind_year
                         and product_code = :bind_product
                         and cat          = :bind_cat
                         and channel      = case :bind_channel when '||'''%'''||' then channel 
                                                               else :bind_channel end';

    execute immediate v_quert_stmt
    into v_qty
    using case when p_current_month + p_months_before > 12 then case when p_current_month + p_months_before > 24 then p_year + 2
                                                                    else p_year + 1
                                                                end
              else p_year  end,
          P_Product_Code, 
          P_Category,
          p_channel,
          p_channel;

    Return  V_Qty;
end after_current_date;