SQL JOIN条件时间格式错误

时间:2017-11-20 23:27:57

标签: join conditional-statements ibm-midrange datetime-format db2-400

我正在研究用于访问"绿屏"的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`

3 个答案:

答案 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