2012-05-04 10 views
0

に私たちに電話をかける電話ダイヤラーがあります。に地域のガス価格について知らせてください。SQL AS/400 - 店舗ごとの製品の価格を抽出する

我々は、コールに関する情報を格納する場所を3つのテーブル(WBDAPP00、WBDCIE00、WBDCIA00)

WBDAPP00がある持っています。
DANOID = ID
DA#INTDA#INDDA#TELは=電話番号
DA#ENVは=グループコールの数は、我々はいくつかの店に1つのメッセージを送信します。
DASTATは、コールの状態を=私たちはグループに関する情報を格納場所
DADTHRは=最後のステータス変更

WBDCIE00のタイムスタンプがある(一時停止中に、キャンセルたちによって確認され、実行されている、店によって確認してください)店舗の CIE#EN = ID
CIEDHC =コールが有効であるタイムスタンプが、我々は価格がために=定期
CIE$PLのために= 14H30
CIE$ORで価格を価格を変更します伝えるために朝呼び出すことができますPL私たちは
CIE$SP

WBDCIA00は補足情報についてWBDAPP00
CIA#ST =店舗
CIA#APのID =コールのIDであるディーゼルのスーパー
CIE$DI =価格の料金を=
CIE#EN =グループコールのID
CIABAN =これは店舗のコンパニティー番号です

これは、これは、テーブル間の関係であり、これら3つのテーブル

SELECT * FROM PRDCM/WBDAPP00 WHERE DA#ENV = 17258 OR DA#ENV = 17257 
 
+--------+--------+--------+---------+--------+--------+----------------------------+-----------+--------+ 
| DANOID | DA#INT | DA#IND | DA#TEL | DA#ENV | DASTAT |   DADTHR   | DAPARM | DAMUSR | 
+--------+--------+--------+---------+--------+--------+----------------------------+-----------+--------+ 
| 100420 |  1 | 418 | 9600055 | 17257 | 4 | 2012-05-07-09.15.04.768228 |1;2;1;1;1;1| ISALAP | 
| 100421 |  1 | 819 | 7346491 | 17258 | 0 | 2012-05-07-09.23.32.362971 |0;4;0;1;0;0| ISALAP | 
| 100422 |  1 | 819 | 7624747 | 17258 | 1 | 2012-05-07-09.24.28.042330 |0;3;1;1;0;1| ISALAP | 
| 100423 |  1 | 819 | 6377874 | 17258 | 0 | 2012-05-07-09.23.32.803073 |0;3;0;1;0;1| ISALAP | 
| 100424 |  1 | 819 | 8742844 | 17258 | 1 | 2012-05-07-09.24.25.347116 |1;1;1;1;0;1| ISALAP | 
| 100425 |  1 | 819 | 8255744 | 17258 | 0 | 2012-05-07-09.23.33.207688 |1;3;1;1;0;1| ISALAP | 
+--------+--------+--------+---------+--------+--------+----------------------------+-----------+--------+ 
SELECT * FROM PRDCM/WBDCIE00 WHERE CIE#EN = 17258 OR CIE#EN = 17257 
 
+--------+----------------------------+--------+--------+--------+--------+ 
| CIE#EN |   CIEDHC   | CIE$OR | CIE$PL | CIE$SP | CIE$DI | 
+--------+----------------------------+--------+--------+--------+--------+ 
| 17257 | 2012-05-04-17.00.00.000000 |  0 |  0 |  0 | 1,359 | 
| 17258 | 2012-05-07-09.30.00.000000 | 1,354 |  0 |  0 |  0 | 
+--------+----------------------------+--------+--------+--------+--------+ 
SELECT * FROM PRDCM/WBDCIA00 WHERE CIA#EN = 17258 OR CIA#EN = 17257 
 
+--------+--------+--------+--------+ 
| CIA#ST | CIA#AP | CIA#EN | CIABAN | 
+--------+--------+--------+--------+ 
|  96 | 100420 | 17257 |  2 | 
| 316 | 100421 | 17258 |  4 | 
| 320 | 100422 | 17258 |  3 | 
| 321 | 100423 | 17258 |  3 | 
| 338 | 100424 | 17258 |  1 | 
| 366 | 100425 | 17258 |  3 | 
+--------+--------+--------+--------+ 

の出力例である
CIA#AP = DANOID
CIA#EN = CIE#EN = DA#ENV私は最後CIE$OR(0ではない)を抽出したい

、各CIA#STの最後のCIE$DI(0ではありません)。
最後のものはCIEDHC(Descの順)で決まります。 DASTATは、1または4にする必要があります。

これは私が上記のデータから抽出したいしたいの例です:

 
+--------+--------+--------+ 
| CIA#ST | CIE$OR | CIE$DI | 
+--------+--------+--------+ 
|  96 |  0 | 1,359 | 
| 316 | 1,354 |  0 | 
| 320 | 1,354 |  0 | 
| 321 | 1,354 |  0 | 
| 338 | 1,354 |  0 | 
| 366 | 1,354 |  0 | 
+--------+--------+--------+ 

またはこのような、それは理想的ではないのですが、私はこのケースで

 
+--------+-------------+-------+ 
| CIA#ST | productType | price | 
+--------+-------------+-------+ 
|  96 |   3 | 1,359 | 
| 316 |   6 | 1,354 | 
| 320 |   6 | 1,354 | 
| 321 |   6 | 1,354 | 
| 338 |   6 | 1,354 | 
| 366 |   6 | 1,354 | 
+--------+-------------+-------+ 
をそれに耐えます

AS400を知らない人のために、TOP 1と等価であり、LIMIT 1

LAST AS400には存在しないので、私は副選択で試してみましたが、あなたはORDER BYFETCH FIRST 1 ROWS ONLYを使用することはできません SELECT Column1,Column2 FROM table1 ORDER BY Column2 DESC LIMIT 1

によって SELECT LAST(Column1) AS test FROM table1 を交換する必要があります。
私たちはPTFなしでV5R1に入っています。

これは、私はすべてのご提案を試してみましょう抽出

SELECT CIA#ST,CIE$OR,CIE$DI,CIEDHC 
FROM PRDCM/WBDAPP03 
INNER JOIN PRDCM/WBDCIE01 ON CIE#EN = DA#ENV 
INNER JOIN PRDCM/WBDCIA01 ON CIA#AP = DANOID 
WHERE DASTAT IN (1,4) 
ORDER BY CIEDHC,DA#ENV 
FETCH FIRST 5 ROWS ONLY 
 
+--------+--------+--------+----------------------------+ 
| CIA#ST | CIE$OR | CIE$DI |   CIEDHC   | 
+--------+--------+--------+----------------------------+ 
|  88 | 1,014 | 1,039 | 2010-08-25-09.00.00.000000 | 
|  89 | 1,014 | 1,039 | 2010-08-25-09.00.00.000000 | 
|  90 | 1,014 | 1,039 | 2010-08-25-09.00.00.000000 | 
|  91 | 1,014 | 1,039 | 2010-08-25-09.00.00.000000 | 
| 119 | 1,084 |  0 | 2010-08-25-09.00.00.000000 | 
| 522 | 1,014 | 1,039 | 2010-08-25-09.00.00.000000 | 
+--------+--------+--------+----------------------------+ 

のexempleです。

+0

'CIE $ OR = 1.587'の行がないので、サンプル/結果データを修正する必要があります。また、あなたがリストした関係を考えれば、 'CIA#ST = 119'を' CIE $ DI = 1.120'に接続できるようなリンクはないようです。あなたのデータを匿名化することは素晴らしいですが、私はこれらの3つのテーブルから有用なものを得ることはできないだろうと思っています(電話番号以外にも)。これまでに試したことを示してもらえますか?ちょうど私たちは何がうまくいかないかを知っていますか?お使いのOSのバージョンを記入してください(私はV6R1 +を想定していますが)。 –

+0

これは、サブクエリと集約グループを巧みに使用して解決できます。 'WBDCIA00'と' WBDAPP00'には2つの異なる結合条件があります。 CIA#AP = DANOID'と 'CIA#EN <> DA#ENV'の関係が1つの試合に存在することはありますか?テーブルとフィールドの簡単な説明を提供するかどうかを判断する方が簡単かもしれません。 – jamesallman

+0

@ X-Zero - >私は実際のデータを入れる権限を持っていますので、私はそれを編集しました。私は新しい試みを追加します。私はas400のバージョンも追加しました。 –

答えて

0

ここであなたのスキーマについてちょっと気が狂っています。私は何か非正規化がありますが、それは他のもの(特に多値列ですか?)です。しかし、おそらくそれを変更する能力は限られているので、可能ならば、データベースがより良いものになるので、少なくともV6R1(これは私たちが行っているもの)にアップグレードすることを検討するべきです。ありがたいことに、あなたはまだCTEを持っていますが、それは少し助けになります。

私は、呼び出し時間によって与えられていない、何がしたいことは1または4のようにDASTATでその店のための呼び出しで(CIEDHCによって与えられた)ストアの最新の価格変更であると仮定すると(そうです以前のグループ通話が後の通話後に「確認済み」の場合はどうなりますか?)。言い換えれば、これは最後の「確認された」変更ではなく、最後に「入力された」変更です。

また、実際の店舗IDがすべて定義された「店舗」テーブルがあるとします。しかし、あなたがそれをリストにしなかったので、私はCTEを作りました。結果のステートメントでそれを交換することができます(おそらくそうすべきです)。

WITH Store (storeId) as (
      SELECT DISTINCT cia#st 
      FROM Wbdcia00), 
    Price_Change (callGroup, occurredAt, productType, newPrice) as (
        SELECT cie#en, ciedhc, 1, cie$or 
        FROM Wbdcie00 
        WHERE cie$or > 0 
        UNION ALL 
        SELECT cie#en, ciedhc, 4, cie$di 
        FROM Wbdcie00 
        WHERE cie$di > 0), 
    Confirmed_Changes (storeId, occurredAt, productType, newPrice) as (
         SELECT WarehouseCall.cia#st, Change.occurredAt, 
           Change.productType, Change.newPrice 
         FROM Wbdcia00 as WarehouseCall 
         JOIN Wbdapp00 as Call 
         ON Call.danoid = WarehouseCall.cia#ap 
         AND Call.dastat IN (1, 4) 
         JOIN Price_Change as Change 
         ON Change.callGroup = da#env), 
    Latest_Change (storeId, productType, newPrice) as (
        SELECT Actual.storeId, Actual.productType, Actual.newPrice 
        FROM Confirmed_Changes as Actual 
        EXCEPTION JOIN Confirmed_Changes as Remove 
        ON Remove.storeId = Actual.storeId 
        AND Remove.productType = Actual.productType 
        AND Remove.occurredAt > Actual.occurredAt) 
SELECT store.storeId, COALESCE(Regular.newPrice, 0) as regularPrice, 
         COALESCE(Diesel.newPrice, 0) as dieselPrice 
FROM Store 
LEFT JOIN Latest_Change as Regular 
ON Regular.storeId = Store.storeId 
AND Regular.productType = 1 
LEFT JOIN Latest_Change as Diesel 
ON Diesel.storeId = Store.storeId 
AND Diesel.productType = 4 

注意すべきいくつかの事柄 -
私はあなたが実際にこれを使用すると、両方の価格が記載されていると、出て行った個々のコールを探していないことを意味し、製品に0の価格を与えていなかった考え出し - それぞれの製品について、最後に起こった変更を行うつもりです。だから私は私のようにテーブルをピボット/アンピボットしたのです。
言うまでもなく、このステートメントは最後に入力された変更が「確認済み」であることを報告します。ただし、ではなく、の最後の確認(dadthrと表示)です。

+0

私はこれらのファイルの構造を選択しませんでした。私はas400バージョンを変更することはできません。私のダイヤラで管理されている店舗を抽出したいので、このソリューションはほぼ完璧です。カンマとスペルミスのスペルが間違っていました。どのように私はこのSQLに最後の定期的かつ最後のディーゼルを出力したいのですか? 'Latest_Change'は最後の定期的または最後のディーゼル価格のみを出力します。 –

+0

#corrected errors、thanks# - 「Latest_Change」は、行ごとの最後の正規/ディーゼルのみを出力します(しかし、比較では製品タイプを無視するエラーが発生しました。だからこそ、私はそれの外で最終的な 'SELECT'を持っているのです。' LEFT JOIN'はそのテーブルの2倍です(定期的に1回、ディーゼルごとに1回)。これは、指定された店舗の列のうち最後の列を取得する唯一の方法で、**同じ行にはない**ことがあります。 –

+0

'Latest_Change'は再び正しくありません。例えば、店舗502は、ディーゼルのすべての可能な価値を伴う通常の価格として常に1.394の51倍である。 –

関連する問題