目标是从
YYYY
中提取A.SCC_ROW_ADD_DTTM
,格式为DateTm
使用 peoplesoft 查询管理器,添加希望从 DateTm 字段中提取年份的表达式。
在 DateTm 字段上运行查询以下列格式显示日期:03/19/2017 12:00:23PM
所以我尝试了
TO_CHAR(TO_DATE(A.SCC_ROW_ADD_DTTM, 'MM/DD/YYYY HH:MI:SSPM'), 'YYYY')
但是一直报错not a valid month (50,380), but every date in the list in the months starts with months in the format of XX (01-12).完整代码如下
SELECT A.ITEM_TYPE, B.DESCR, SUM( A.ITEM_AMT- A.APPLIED_AMT), TO_CHAR(TO_DATE(TO_CHAR(CAST((A.SCC_ROW_ADD_DTTM) AS TIMESTAMP),'YYYY-MM-DD-HH24.MI.SS.FF'), 'MM/DD/YYYY HH:MI:SSPM'), 'YYYY'), TO_CHAR(CAST((A.SCC_ROW_ADD_DTTM) AS TIMESTAMP),'YYYY-MM-DD-HH24.MI.SS.FF')
FROM PS_ITEM_SF A, PS_ITEM_TYPE_TBL B
WHERE ( B.ITEM_TYPE = A.ITEM_TYPE
AND ( A.ITEM_TYPE IN ('600000050010','600000050020','600000050030')
AND B.EFFDT =
(SELECT MAX(B_ED.EFFDT) FROM PS_ITEM_TYPE_TBL B_ED
WHERE B.SETID = B_ED.SETID
AND B.ITEM_TYPE = B_ED.ITEM_TYPE
AND B_ED.EFFDT <= SYSDATE) ))
GROUP BY A.ITEM_TYPE, B.DESCR, TO_CHAR(TO_DATE( TO_CHAR(CAST((A.SCC_ROW_ADD_DTTM) AS TIMESTAMP),'YYYY-MM-DD-HH24.MI.SS.FF'), 'MM/DD/YYYY HH:MI:SSPM'), 'YYYY'), A.SCC_ROW_ADD_DTTM
HAVING ( SUM( A.ITEM_AMT- A.APPLIED_AMT) > 0)
ORDER BY 1
我试过更改日期格式,但从任何内容更改时都会出现更严重的错误,但现在的表达式是什么,我只是不知道为什么它说月份不正确。
编辑:我现在注意到 peoplesoft 查询管理器自动将字段转换为时间戳,没有办法阻止这种情况,所以我认为没有办法解决这个问题。
错误、名称和描述方式表明
SCC_ROW_ADD_DTTM
是 DATE 列,而不是 VARCHAR2 - 这很好,因为您不应该将日期存储为字符串。
因为它已经是一个日期,所以您应该 not 做
TO_DATE(SCC_ROW_ADD_DTTM, ...)
或您现在拥有的其他一些转换。日期以内部格式存储,并通过明确的TO_CHAR()
或由您的客户自动转换为人类可读的内容。看起来您的客户端在您查询表时将值显示为 MM/DD/YYYY HI:MI:SSPM。这并不意味着该列本身具有该(或任何)格式。
您需要删除大部分转换:
SELECT
A.ITEM_TYPE,
B.DESCR,
SUM(A.ITEM_AMT - A.APPLIED_AMT),
TO_CHAR(A.SCC_ROW_ADD_DTTM, 'YYYY'),
TO_CHAR(CAST(A.SCC_ROW_ADD_DTTM AS TIMESTAMP), 'YYYY-MM-DD-HH24.MI.SS.FF')
FROM PS_ITEM_SF A
JOIN PS_ITEM_TYPE_TBL B
ON B.ITEM_TYPE = A.ITEM_TYPE
WHERE A.ITEM_TYPE IN ('600000050010', '600000050020', '600000050030')
AND B.EFFDT = (
SELECT MAX(B_ED.EFFDT)
FROM PS_ITEM_TYPE_TBL B_ED
WHERE B.SETID = B_ED.SETID
AND B.ITEM_TYPE = B_ED.ITEM_TYPE
AND B_ED.EFFDT <= SYSDATE
)
GROUP BY A.ITEM_TYPE, B.DESCR, A.SCC_ROW_ADD_DTTM
HAVING SUM(A.ITEM_AMT - A.APPLIED_AMT) > 0
ORDER BY 1
我还切换到现代连接语法,简化了 group by 子句等
如果您的专栏实际上是 TIMESTAMP 那么以上所有内容都适用,只需删除
CAST()
调用(fiddle)。即使使用 DATE,您也可以删除它并将固定的 .000000
或只是 .0
添加到格式模型中以进行显示。
你也可以做
EXTRACT(YEAR FROM ...)
而不是 TO_CHAR(..., 'YYYY')
,这会将结果作为数字而不是字符串 - 取决于你想要的。
Peoplesoft 将自动执行 TO_CHAR,因此您需要将其转换回日期,然后再次转换为 TO_CHAR(...,'YYYY'),这通常是我使用表达式执行此操作的方式。
PS/Query 很奇怪,但我想出了怎么做。创建一个字符类型的表达式并使用 substr(A.SCC_ROW_ADD_DTTM,1,4) 获取年份的前 4 个字符。
我用这样一个简单的 PSOPRDEFN 查询来完成它:
生成此查询:
SELECT A.OPRID, TO_CHAR(A.LASTSIGNONDTTM,'YYYY-MM-DD-HH24.MI.SS."000000"'),
substr( TO_CHAR(A.LASTUPDDTTM,'YYYY-MM-DD-HH24.MI.SS."000000"'),1,4)
FROM PSOPRDEFN A
这是当年的产出:
这里的关键是PS/Query中的表达式文本“substr(A.LASTUPDDTTM,1,4)”被翻译成substr( TO_CHAR(A.LASTUPDDTTM,'YYYY-MM-DD-HH24.MI.SS." 000000"'),1,4) 对于 Oracle。