2017-11-20 33 views
0

"Green Screen" AS400 IBM iSERIES(VBAを使用)にアクセスするためのSQLコードを作成中です.ADODB接続を介して接続しています。 SQLのバージョン、私はSQLの初心者です)。SQL JOIN条件時刻形式エラー

コードが正常に動作していますが、最後のLEFT JOINに別の「AND」条件を追加して、コードに[(PO.STKDT- PO.ACTDT) < 40]。つまり、(株日)から(作成日)を差し引いた金額は40日未満です。

だから私のようなものを追加したい:

AND (date(timestamp((PO.STKDT + 19000000) concat '000000')) - date(timestamp((PO.ACTDT + 19000000) concat '000000'))) <40 

コードは、この非常に条件なしで細かい動作しますが、私はこの条件を追加するとき、それは私にエラー「SQL0181与える:日付における値、時刻、またはタイムスタンプを文字列は無効です "。

すべてのヘルプは、その形式1171119から11/19に変換するために、私は「TIMESTAMP」と「DATE」はSTKDTとACTDT日付列に接続していることに注意してくださいAND条件エラー

を解決するためには理解されるであろう/ 2017。そして、私はこのフォーマットでカラムデータを正しく引っ張っているパラメータを持っています。

ありがとうございました!ここで

は私の完全なコードです:

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

緑色の画面にはSQLでアクセスできません。これを使用してデータベースを照会します。 IBM iの場合、そのデータベースはおそらくDB2 for iです。 – jmarkmurphy

答えて

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

+0

Charlesに感謝します。あなたが提供したコードを試しました。そして、列データをパラメータとして正しく引っ張りました。しかし、私が条件として使用したとき、私は上記のエラーと同じ結果を返しました。 – MrKen

+1

@MrKenおそらく無効な日付を含む列があります。ゼロが頭に浮かびますが、1170229も失敗します。 – Charles

0

DAYS機能を調べることができます。元のフィールドが有効な日付フィールドであれば、あなたの式はのように簡単になります:日付経由

DAYS(PO.STKDT) - DAYS(PO.ACTDT) < 40 

少し複雑最初に変換するには/あなたがやっている方法にタイムスタンプが、それでも動作するはずです。また、を参照してください:Calculating how many days are between two dates in DB2?

+0

リチャード、私にエラーを出したおかげでSQL0171:引数DAYSが有効でない – MrKen

0

私はあなたがジョイン句(彼らはジョイン基準ではない)のPOのフィルタ条件を移動し、where句に移動します。これは単なる意味的なことであり、実際にはクエリにはまったく影響しません。すべてのフィルタ条件が1つの場所にあり、すべての結合条件が別の場所にあるため、理解が容易になります。次に、timestamp_formatを使用して、数字の日付をtimestampの値に変更します。 timestampを0001年1月1日以降の日数に変換します。これらを減算して40と比較することができます。

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) 

WHERE X.ITNBR != 'TEST%' 
    AND PO.STAIC != 99 
    AND PO.ACTDT between '" & Range("AA1") & "' and '" & Range("AB1") & "' 
    AND days(timestamp_format(PO.STKDT + 19000000, 'YYYYMMDD')) - 
     days(timestamp_format(PO.ACTDT + 19000000, 'YYYYMMDD')) < 40 

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

ありがとうございますjmarkmurphy、私は最初の作業コードを2回(40日間の余分な条件を追加しないで)、1回はLEFT JOINと私がWHERE節でそれを持っていたもうひとつの時に、それぞれ私は633421と246321の数がそれぞれ違ってきました。 WHERE節がPOテーブルだけでなくすべてのテーブルの結果を制限するように見えます。しかし、LEFT JOINの条件だけを入れたいです。 – MrKen