在in语句中具有已定义变量的sql pivot函数
有人能告诉我怎样才能做到这一点吗?我要么得到“ORA-56901:pivot | unpivot值不允许使用非常量表达式”,要么得到“ORA-00917:missing comma”,这取决于我是否在in语句中加引号&mb1。谢谢大家!在in语句中具有已定义变量的sql pivot函数,sql,oracle,pivot,oracle-sqldeveloper,Sql,Oracle,Pivot,Oracle Sqldeveloper,有人能告诉我怎样才能做到这一点吗?我要么得到“ORA-56901:pivot | unpivot值不允许使用非常量表达式”,要么得到“ORA-00917:missing comma”,这取决于我是否在in语句中加引号&mb1。谢谢大家! define mb1= ADD_MONTHS(TRUNC(SYSDATE,'MM'),-1); select * from ( select COLLECTOR ,Month ,low_activity_days fro
define mb1= ADD_MONTHS(TRUNC(SYSDATE,'MM'),-1);
select *
from
( select COLLECTOR
,Month
,low_activity_days
from dwh_prod.low_activity_days_collect_t) src
pivot
(
sum(low_activity_days)
for month in ('&mb1')
) piv;
您可以将替换设置为固定值,这样它就不会试图在pivot子句中进行计算。在处理日期时,可以生成日期文字:
set termout off
column x_mb1 new_value mb1
select 'date ''' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE,'MM'),-1),
'YYYY-MM-DD') || '''' as x_mb1
from dual;
set termout on
select * from (
select COLLECTOR ,Month ,low_activity_days
from dwh_prod.low_activity_days_collect_t
) src
pivot ( sum(low_activity_days) for month in (&mb1) ) piv;
第一个查询(输出被termout
隐藏)生成一个字符串:
select 'date ''' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE,'MM'),-1),
'YYYY-MM-DD') || '''' as x_mb1
from dual;
X_MB1
-----------------
date '2017-03-01'
然后将&mb
设置为该值。然后,查询中的替换将变为:
select * from (
select COLLECTOR ,Month ,low_activity_days
from dwh_prod.low_activity_days_collect_t
) src
pivot ( sum(low_activity_days) for month in (date '2017-03-01') ) piv
原始代码的问题在于,在替换的pivot子句中引用了sysdate
,这会引发ORA-56901异常(因为sysdate
不是常量)。可以在轴中使用任何固定值,因此可以执行以下操作:
使用字符串周围的qoutes作为定义的一部分,或
define mb1='01-APR-17'
... for month in ('&mb1') ) piv;
没有,或其他变化。但因为这些最终都是字符串,所以您依赖于隐式日期转换,并且依赖于NLS设置;对于我生成的日期文本,这不是问题。如果您真的想使用该日期格式,您仍然可以:
define mb1='01-APR-17'
... for month in (to_date('&mb1', 'DD-MON-RR')) ) piv;
或者使用new\u values
方法选择特定格式的日期:
column x_mb1 new_value mb1
select to_char(add_months(trunc(sysdate, 'MM'), -1), 'DD-MON-RR') as x_mb1 from dual;
... for month in (to_date('&mb1', 'DD-MON-RR')) ) piv;
不过,使用日期文字格式对我来说似乎更简单
但我不确定为什么旋转单个值特别有用。也许您真正的查询做的更多,但简单的聚合和过滤器在这里看起来更合适:
select collector, sum(low_activity_days)
from low_activity_days_collect_t
where month = add_months(trunc(sysdate, 'MM'), -1)
group by collector;
如果你想要一个12个月的滚动总结,你不需要动态地构建轴心;您可以基于当前日期生成月份偏移量,这将为您提供一个固定的数值范围(而不是日期),例如:
select * from (
select collector, low_activity_days,
months_between(trunc(sysdate, 'MM'), month) as month_offset
from low_activity_days_collect_t
where month >= add_months(trunc(sysdate, 'MM'), -13)
and month < trunc(sysdate, 'MM')
) src
pivot (sum(low_activity_days) as months_ago
for month_offset in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
不过,您可能会发现使用适当的报告工具来查询和格式化/显示结果更容易。您可以将替换设置为固定值,这样就不会试图在pivot子句中进行计算。在处理日期时,可以生成日期文字:
set termout off
column x_mb1 new_value mb1
select 'date ''' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE,'MM'),-1),
'YYYY-MM-DD') || '''' as x_mb1
from dual;
set termout on
select * from (
select COLLECTOR ,Month ,low_activity_days
from dwh_prod.low_activity_days_collect_t
) src
pivot ( sum(low_activity_days) for month in (&mb1) ) piv;
第一个查询(输出被termout
隐藏)生成一个字符串:
select 'date ''' || TO_CHAR(ADD_MONTHS(TRUNC(SYSDATE,'MM'),-1),
'YYYY-MM-DD') || '''' as x_mb1
from dual;
X_MB1
-----------------
date '2017-03-01'
然后将&mb
设置为该值。然后,查询中的替换将变为:
select * from (
select COLLECTOR ,Month ,low_activity_days
from dwh_prod.low_activity_days_collect_t
) src
pivot ( sum(low_activity_days) for month in (date '2017-03-01') ) piv
原始代码的问题在于,在替换的pivot子句中引用了sysdate
,这会引发ORA-56901异常(因为sysdate
不是常量)。可以在轴中使用任何固定值,因此可以执行以下操作:
使用字符串周围的qoutes作为定义的一部分,或
define mb1='01-APR-17'
... for month in ('&mb1') ) piv;
没有,或其他变化。但因为这些最终都是字符串,所以您依赖于隐式日期转换,并且依赖于NLS设置;对于我生成的日期文本,这不是问题。如果您真的想使用该日期格式,您仍然可以:
define mb1='01-APR-17'
... for month in (to_date('&mb1', 'DD-MON-RR')) ) piv;
或者使用new\u values
方法选择特定格式的日期:
column x_mb1 new_value mb1
select to_char(add_months(trunc(sysdate, 'MM'), -1), 'DD-MON-RR') as x_mb1 from dual;
... for month in (to_date('&mb1', 'DD-MON-RR')) ) piv;
不过,使用日期文字格式对我来说似乎更简单
但我不确定为什么旋转单个值特别有用。也许您真正的查询做的更多,但简单的聚合和过滤器在这里看起来更合适:
select collector, sum(low_activity_days)
from low_activity_days_collect_t
where month = add_months(trunc(sysdate, 'MM'), -1)
group by collector;
如果你想要一个12个月的滚动总结,你不需要动态地构建轴心;您可以基于当前日期生成月份偏移量,这将为您提供一个固定的数值范围(而不是日期),例如:
select * from (
select collector, low_activity_days,
months_between(trunc(sysdate, 'MM'), month) as month_offset
from low_activity_days_collect_t
where month >= add_months(trunc(sysdate, 'MM'), -13)
and month < trunc(sysdate, 'MM')
) src
pivot (sum(low_activity_days) as months_ago
for month_offset in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
不过,您可能会发现,使用适当的报告工具来查询和格式化/显示结果会更容易。谢谢。你是对的。我必须在过去的12个月里这样做,但我需要这是一个连续的12个月。我刚刚用了一个月的时间尝试让它工作。我尝试了你的代码,包括它的几个变体,我不断得到错误:ORA-00932:不一致的数据类型:预期日期得到编号00932。00000-“不一致的数据类型:应为%s获得%s”*原因:*操作:第22行错误列:53表中列的数据类型是什么?月份列的格式为dd Mon yy。其余的是收集器VARCHAR2(133字节)COLL_GROUP VARCHAR2(22字节)COLL_TYPE VARCHAR2(30字节)DAY VARCHAR2(9字节)LOW_ACTIVITY_DAYS NUMBER MONTH DATE SUB_GROUP VARCHAR2(30字节)。我不确定您是如何看到这个错误的,我用这些数据类型尝试了一些虚拟数据,没有发现任何问题。但我不知道第22行第53个字符在你的剧本中指向什么,所以可能是从别处来的?谢谢你,亚历克斯。你是对的。我必须在过去的12个月里这样做,但我需要这是一个连续的12个月。我刚刚用了一个月的时间尝试让它工作。我尝试了你的代码,包括它的几个变体,我不断得到错误:ORA-00932:不一致的数据类型:预期日期得到编号00932。00000-“不一致的数据类型:应为%s获得%s”*原因:*操作:第22行错误列:53表中列的数据类型是什么?月份列的格式为dd Mon yy。其余的是收集器VARCHAR2(133字节)COLL_GROUP VARCHAR2(22字节)COLL_TYPE VARCHAR2(30字节)DAY VARCHAR2(9字节)LOW_ACTIVITY_DAYS NUMBER MONTH DATE SUB_GROUP VARCHAR2(30字节)。我不确定您是如何看到这个错误的,我用这些数据类型尝试了一些虚拟数据,没有发现任何问题。但我不知道第22行第53个字符在你的剧本中指的是什么,所以可能是从别处来的?