使用三个表中的值查找保证金VBA,SQL

时间:2014-09-16 17:58:35

标签: sql excel vba db2

已经坚持了好几个月。以下是示例表,我正在使用的代码以及我遇到的问题:

ITEM

MFGR | CLR | PAT | Desc1 | Desc2 | Price | Cost
-----|-----|-----|-------|-------|-------|------
MMM  | 001 | 001 | BLAH  | BLAH  | MMM01 | MMM01
MMM  | 002 | 002 | BLAH  | BLAH  | MMM02 | MMM02
MMM  | 003 | 003 | BLAH  | BLAH  | MMM03 | MMM03
MMM  | 004 | 004 | BLAH  | BLAH  | MMM04 | MMM04
MMM  | 005 | 005 | BLAH  | BLAH  | MMM04 | MMM05


PRICE
/* The P1, P2, P3, etc. are prices for different quantities */
/* T1 tier is just better pricing and quantity breaks for high volume customer */

PRICE | TIER | LISTP | P1 | P2 | P3 | P4 | P5 | P6 | P7 | P8 | P9 | P10 | P11 | P12
------|------|-------|----|----|----|----|----|----|----|----|----|-----|-----|-----
MMM01 |  LP  |  $10  |$10 | $9 | $8 | $7 | $6 |    |    |    |    |     |     |     
MMM01 |  T1  |  $10  |$8  | $7 | $6 | $5 | $4 |    |    |    |    |     |     |
MMM02 |  LP  |  $20  |$20 |$18 |$16 |$14 |$12 |    |    |    |    |     |     |
MMM02 |  T1  |  $20  |$16 |$14 |$12 |$10 | $8 |    |    |    |    |     |     |
....


COST

 COST | LASTC 
------|-------
MMM01 | $5
MMM02 | $10

所以我使用VBA和SQL从IBM DB2数据库直接导入Excel。由于某种原因,我没有任何其他选项或应用程序,所以这就是我必须做的事情。

我想要完成的是生成一个带有保证金的项目列表 - 无论是定价,价格等级还是数量中断 - 低于使用VBA InputBox指定的GPM。任何价格低于X的商品都需要显示在报告上。

这是我一直在使用的代码和我遇到的两个问题,我将随后解释:

SELECT i.MFGR || i.CLR || i.PAT as Item, i.DESC1 as Description1, 
i.DESC2 as Description2, i.PRICE as PClass, i.COST as CClass, p.TIER as Tier, 
c.LASTC as Cost, p.LISTP as List, ((p.LISTP-c.LASTC)/p.LISTP) as GPM, p.P2 as Price2, 
((p.P2-c.LASTC)/p.P2) as GPM2, p.P3 as Price3, ((p.P3-c.LASTC)/p.P3) as GPM3, 
p.P4 as Price4, ((p.P4-c.LASTC)/p.P4) as GPM4, p.P5 as Price5, 
((p.P5-c.LASTC)/p.P5) as GPM5, p.P6 as Price6, ((p.P6-c.LASTC)/p.P6) as GPM6, 
p.P7 as Price7, ((p.P7-c.LASTC)/p.P7) as GPM7, p.P8 as Price8, 
((p.P8-c.LASTC)/p.P8) as GPM8, p.P9 as Price9, ((p.P9-c.LASTC)/p.P9) as GPM9, 
p.P10 as Price10, ((p.P10-c.LASTC)/p.P10) as GPM10, p.P11 as Price11, 
((p.P11-c.LASTC)/p.P11) as GPM11, p.P12 as Price12, ((p.P12-c.TLASTC)/p.P12) as GPM12 
FROM ITEM i
LEFT JOIN COST c
     ON i.COST = c.COST
LEFT JOIN PRICE p
     ON i.PRICE = p.PRICE
WHERE (((p.LIST-c.LASTC)/p.LIST) < '" & margin & "') 
ORDER BY i.MFGR || i.CLR || i.PAT

第一个问题:这显示了层LP的价格中断,但不显示T1层的价格中断。它只显示T1的LISTP列。它应该显示它之后的所有P1,P2,P3等。是的,我已经验证我的T1文件确实有P1,P2等值。

但是这个查询并没有给我我真正想要的东西,因为我希望它能够以低于某个GPM的价格提取任何项目。所以我将where语句修改为以下内容:

/* I will eventually add margin calculations for P3, P4, etc. */
/* but can't even get this to work, so not point in it yet */

WHERE (((p.LIST-c.LASTC)/p.LIST) < '" & margin & "') OR 
(((p.P2-c.LASTC)/p.P2) < '" & margin & "' )

所以即使我输入的保证金是20%而且标价超过20%,但是P2低于,该项目仍应该出现,对吧?不。每次出现错误时都会出现错误:运行时错误&#39; 1004&#39;:常规ODBC错误。如果我输入列名错误,我通常会得到这个,但我可以向你保证,我已经完成了我的尽职调查并且我的所有列名都是正确的,应该导入的数据已经过验证实际存在,我已经调整了数据为了获得可预测的结果,尝试了括号的每个组合等。

如果我将OR更改为AND,则ODBC错误会消失,但这并不是我想要做的事情,因为这就是说LP和P2都低于边距...我想要或者。

那么我做错了什么?

1 个答案:

答案 0 :(得分:0)

SQLFiddle应该让您走上正确的轨道

这是针对SQL Server的,但我相信所有命令都是标准的,所以应该在DB2中工作。

DECLARE @TARGET FLOAT = 0.2

SELECT P.PRICE, P.TIER, P.P, P.PRICES, C.LCOST, (P.PRICES-C.LCOST)/P.PRICES MARGIN, @TARGET TARGET
FROM   (SELECT PRICE, TIER, P, PRICES
        FROM   PRICE
        UNPIVOT
        (
          PRICES 
          FOR P IN (LISTP, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12)
        ) U
       WHERE PRICES <> 0) P
       LEFT JOIN
       COST C on P.PRICE=C.COST
WHERE  (P.PRICES-C.LCOST)/P.PRICES < @TARGET;

这样做是UNPIVOT你拥有的表,所以你得到的价格转换为行的列 - 然后连接是微不足道的。