SQL AS / 400 - 提取每个商店的产品价格

时间:2012-05-04 14:19:26

标签: sql select ibm-midrange

我们有一个拨打我们商店的电话拨号器告知他们所在地区的汽油价格。

我们有3个表(WBDAPP00,WBDCIE00,WBDCIA00)

WBDAPP00是我们存储有关通话的信息​​的地方 DANOID = ID
DA#INTDA#INDDA#TEL =电话号码
DA#ENV =群组通话的次数,我们向少数商店发送1条消息 DASTAT =通话状态(按商店确认,取消,运行,由我们确认,暂停)
DADTHR =上次状态修改的时间戳

WBDCIE00是我们存储商店组信息的地方 CIE#EN = ID
CIEDHC =通话有效的时间戳,我们可以打电话给早上告诉价格会在14点30分发生变化
CIE$OR =正常的价格 CIE$PL =加号的价格 CIE$SP =超级的价格 CIE$DI =柴油价格

WBDCIA00是有关WBDAPP00的补充信息 CIA#ST =商店的ID
CIA#AP =通话的身份
CIE#EN =群组通话的身份
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提取最后CIE$DI(不是0)和最后CIA#ST(不是0)。
最后一个由CIEDHC(描述顺序)确定。 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的人,FETCH FIRST 1 ROWS ONLY等于TOP 1LIMIT 1

AS400中不存在

LAST所以我需要替换 SELECT LAST(Column1) AS test FROM table1 通过 SELECT Column1,Column2 FROM table1 ORDER BY Column2 DESC LIMIT 1

我尝试过subselect但你不能使用ORDER BYFETCH FIRST 1 ROWS ONLY 我们在V5R1中没有任何PTF。

这是一个提取的例子

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 |
+--------+--------+--------+----------------------------+

我会尝试你所有的建议。

1 个答案:

答案 0 :(得分:0)

坦率地说,我对你的架构有些不满 - 有一些我不满意的非规范化,除此之外(多值列,真的吗?)。但是你可能只有有限的能力来改变它,所以...如果可能的话,你应该考虑升级到至少V6R1(这就是我们所使用的),因为数据库获得了更多好处。值得庆幸的是,你仍然有CTE,这将有所帮助。

我假设您想要的是商店的最新价格变化(由CIEDHC给出),并在DASTAT中调用该商店为1或4,不是< / em>由呼叫时间给出(那么,如果之前的群组呼叫在后一个群组呼叫被'确认'后会发生什么?)。换句话说,这不是最后一次“确认”的变化,而是最后一次“输入”变更。

我还假设你有一个'store'表,定义了所有实际的商店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表示)。