我正在研究用于访问"绿屏"的SQL代码。使用VBA的AS400 IBM iSERIES和我通过ADODB连接进行连接(如果您需要有关连接或SQL版本的更多信息,请告诉我,我是SQL的初学者)。
现在我的代码运行得很好,但我想添加另一个" AND"在最后的LEFT JOIN中的条件使得代码仅考虑存在的数据[(PO.STKDT-PO.ACTDT)< 40]。换句话说,(库存日期)减去(创建日期)少于40天。
所以我想添加类似的内容:
AND ( date(timestamp((PO.STKDT + 19000000) concat '000000')) - date(timestamp((PO.ACTDT + 19000000) concat '000000')) ) <40
代码在没有这个条件的情况下运行正常,但是当我添加这个条件时它会给我一个错误&#34; SQL0181:日期,时间或时间戳字符串中的值无效&#34;。
理解任何帮助以解决AND条件错误
请注意我有&#39; TIMESTAMP&#39;和&#39;日期&#39;附加到STKDT和ACTDT日期列,将其从格式1171119转换为2017年11月19日。我有一个参数,正确地使用此格式提取列数据。
感谢您的帮助!
这是我的完整代码:
SELECT X.ITNBR AS ITEM, X.ITDSC AS DESCRIPTION,
X.CRUS AS CREATE_USER, X.INVFG AS INV_FLAG ,
C1.PURPR AS PO_PRICE, C2.STDUC AS STD_COST,
A.HOUSE AS WHS, A.WHSLC AS WHSLOCATION ,
A.VNDNR AS VENDR,VN.VNAME AS VENDOR_NAME ,
VN.VNAMA, A.MOHTQ AS QTY_ON_HAND,
A.MPUPQ AS QTY_ON_PURCHASE ,A.MALQT AS QTY_ALLOCATED,
(A.MOHTQ+A.MPUPQ-A.MALQT) AS QTY_AVAILABLE,
( (A.MOHTQ+A.MPUPQ-A.MALQT) * C2.STDUC ) AS INV_COST,
K.KIORDCNT AS KB_CARDS, K.KICQTY AS KB_QTY,
K.KICTYP AS KB_TYPE, COUNT( PO.ITNBR ) AS DATA_COUNT ,
AVG(PO.STKPR) AS AVG_PO_PRICE,
CAST(AVG( date(timestamp((PO.STKDT + 19000000) concat '000000')) - date(timestamp((PO.ACTDT + 19000000) concat '000000')) ) AS DECIMAL(50,2) ) AS AVG_LEADTIME,
SUM(PO.QTYOR) AS ALL_QTY_ORDERED,MIN(PO.QTYOR) AS MIN_QTY_ORDERED,
CAST(AVG(PO.QTYOR) AS DECIMAL(50,2) ) AS AVG_QTY_ORDERED,
MAX(PO.QTYOR) AS MAX_QTY_ORDERED
FROM SIM.ENT X
LEFT JOIN SIM.ITEM A ON (A.ITNBR=X.ITNBR)
LEFT JOIN SIM.ITMR C1 ON (C1.ITNBR=A.ITNBR)
LEFT JOIN SIM.ITMV C2 ON (C2.ITNBR=A.ITNBR)
LEFT JOIN SIM.VENN VN ON (VN.VNDNR=A.VNDNR)
LEFT JOIN SIM.KBIM K ON (K.KIITEM=A.ITNBR AND K.KIHOUSE=A.HOUSE)
LEFT JOIN SIM.POIT PO ON (PO.ITNBR=A.ITNBR AND PO.HOUSE=A.HOUSE AND PO.VNDNR=A.VNDNR)
AND PO.STAIC !=99
AND PO.ACTDT between '" & Range("AA1") & "' and '" & Range("AB1") & "' ***AND MYTIMECONDITIONHERE***
WHERE X.ITNBR != 'TEST%'
GROUP BY X.ITNBR, X.ITDSC,X.CRUS,X.INVFG, C1.PURPR, C2.STDUC
,A.HOUSE, A.VNDNR,VN.VNAME, VN.VNAMA, A.WHSLC
,A.MOHTQ,A.MPUPQ,A.MALQT,K.KIORDCNT, K.KICQTY, K.KICTYP`
答案 0 :(得分:0)
为什么要将所有想要查看的日期转换为时间戳?
要将数字CYYMMDD转换为实际日期,您需要构建一个包含'YYYY-MM-DD'的字符串...所以你需要这样的东西:
select date(
substring(char(dec(1171120,7) + 19000000),1,4)
concat '-' concat
substring(char(dec(1171120,7) + 19000000),5,2)
concat '-' concat
substring(char(dec(1171120,7) + 19000000),7,2)
) as theDate
from sysibm.sysdummy1
不是在语句中转换它,而是构建一个转换它的UDF。或者更好的是,下载这样的UDF我建议iDate
答案 1 :(得分:0)
您可能想要检查DAYS功能。如果您的原始字段是有效的日期字段,那么您的表达式将简单如下:
DAYS(PO.STKDT) - DAYS(PO.ACTDT) < 40
首先通过日期/时间戳转换你的方式稍微复杂一点,但应该仍然有效。另请参阅:Calculating how many days are between two dates in DB2?
答案 2 :(得分:0)
首先,我将把你的过滤条件从join子句中移出(它们不是连接条件),然后移到where子句中。这只是一个语义问题,根本不会影响查询。它只是让事情变得更容易理解,因为所有过滤条件都在一个地方,所有的连接标准都在另一个地方。然后我会使用TimeStamp userid ip artist album song id service
2017-01-06 07:00:01 444444 11.11.111.0 Tears For Fears Songs From The Big Chair Everybody Wants To Rule The World S4555 pandora
将数字日期更改为timestamp_format
值。然后将timestamp
转换为自0001年1月1日以来的天数。您可以减去这些并与40进行比较。这是您的查询已根据我的建议修改。
timestamp