【问题标题】:Conditional Value Subtraction on 1 table1 个表的条件值减法
【发布时间】:2013-11-27 16:54:37
【问题描述】:

这是我第一次在这里提问,如果我可以提供更多数据来帮助您帮助我,请告诉我:)


目前,我有一个类似于以下内容的表:
ID  项目  ADJUST_QTY  ADJUST_TYPE  INV_SOURCE&n bsp; INV_DEST  仓库  供应商
1 a12 100一个空alloc 1001 null
2 A12 50 S NULL ALLOC 1001 NULL
3   A12    100                  S                                                                                                                                                                          12345
4   A12    50                    A                                                                                                                                                        12345
5 B12 100 A Alloc Un-Alloc 1002 Null
6 B12 100 A UN-Alloc Alloc 1002 Null

我的查询的输出应该是:
ITEM  ADJUST_QTY  INV_SOURCE  INV_DEST  仓库  供应商
A12 50 NULL ALLOC 1001 NULL(这是ID 1 - ID 2)
A12    -50                  NULL               UN-ALLOC  1001              12345             (这是 ID 4 - ID 3)
B12    100                  ALLOC            UN-ALLOC  1002               NULL              (这是 ID 5)
B12    100                 UN-ALLOC      ALLOC        1002               NULL              (这是 ID 6)

ADJUST_TYPE A = 加,S = 减。我试图找到项目、INV_SOURCE、INV_DEST、WAREHOUSE 和 VENDORASN 相同的 SUM(A) - SUM(S)。目前,我正在使用左连接和分组来尝试实现这一目标,但我没有得到任何结果。我知道有满足我需要的记录,但此时我的查询不正确。

我现在有以下问题:

SELECT 
    I1.ITEM,
    SUM(I1.ADJUST_QTY)-SUM(I2.ADJUST_QTY) AS QUANTITY, 
    I1.INV_SOURCE, 
    I1.INV_DEST,
    I1.WAREHOUSE,
    I1.VENDORASN 
FROM    
    INV_ADJUSTMENT I1 
LEFT JOIN 
    INV_ADJUSTMENT I2 
ON (I2.ADJUST_TYPE='S' 
    AND I2.WAREHOUSE=I1.WAREHOUSE                                     
    AND I2.ITEM=I1.ITEM 
    AND I2.INV_SOURCE=I1.INV_SOURCE 
    AND I2.INV_DEST=I1.INV_DEST 
    AND I2.VENDORASN = I1.VENDORASN) 
WHERE I1.ADJUST_TYPE='A' 
GROUP BY 
    I1.ITEM,
    I1.INV_SOURCE,
    I1.INV_DEST,
    I1.WAREHOUSE,
    I1.VENDORASN, 
    I2.ITEM,
    I2.INV_SOURCE,
    I2.INV_DEST,
    I2.WAREHOUSE,
    I2.VENDORASN;

【问题讨论】:

    标签: math db2 conditional-statements conditional-operator


    【解决方案1】:

    试试这个

    SELECT 
      ITEM, 
      INV_SOURCE, 
      INV_DEST, 
      WAREHOUSE, 
      VENDORASN, 
      SUM( ( if ( ADJUST_TYPE ='S', -ADJUST_QTY , ADJUST_QTY ) ) ) AS ADJUSTMENT
    FROM INV_ADJUSTMENT
    GROUP BY ITEM, INV_SOURCE, INV_DEST, WAREHOUSE, VENDORASN
    

    【讨论】:

    • 注意我忘了添加。我现在在 DB2 上。当我运行上述语句时,我得到 SQLCODE=-104, SQLSTATE=42601, SQLERRMC==;DJUST_TYPE 对应于检测到符号“令牌”的语法错误。由于列名拼写正确,因此不确定是什么原因造成的。
    • OP 被标记为 mysql 所以这就是我写的。 :) 我无权访问 DB2 进行测试,也没有任何重要的经验。您最终的生产环境是 DB2 还是 mysql?
    • 不幸的是,DB2。我们的应用程序是为 SQL 构建的,但是这个特定的客户使用 DB2 并且不会切换 :(
    • 无赖。好吧,我确定您不需要加入,而是需要一个组。在函数中放置条件可能会有点挑剔你添加了多少组括号 - 在 mysql 中:) - 所以我怀疑这是问题所在。但同样,不知道 DB2。您可能需要重新标记问题。
    • 谢谢。进行了编辑。我会弄乱你给的东西,也许尝试使用 Case。再次感谢您的帮助!
    【解决方案2】:

    你能看看下面的查询是否有效。在子查询中添加剩余的连接。

    SELECT l.ITEM,         
       l.ADJUST_QTY - (SELECT ADJUST_QTY 
                  FROM INV_ADJUSTMENT x
                  WHERE x.ITEM = l.ITEM
                  LIMIT 1) total
    FROM INV_ADJUSTMENT l Where l.ADJUST_TYPE = 'S';
    

    这里是fiddle

    【讨论】:

    • 与预期结果相比,您的小提琴给出的答案不正确。当您靠近时,它也不包含足够的列或行来正确测试。另外,它是 mySql,而不是 DB2,尽管很可能有一个可移植的答案。 (我的几乎便携)
    【解决方案3】:

    我认为您可能使情况过于复杂。试试这个:

    SELECT 
     I1.ITEM, 
     SUM(I1.ADJUST_QTY \* case I1.ADJUST_TYPE when 'S' then -1 else 1 end),
     I1.INV_SOURCE, 
     I1.INV_DEST,I1.WAREHOUSE,I1.VENDORASN 
    FROM 
     INV_ADJUSTMENT I1 
    GROUP BY 
     I1.ITEM,I1.INV_SOURCE,I1.INV_DEST,I1.WAREHOUSE,I1.VENDORASN;
    

    请注意,我必须在 SUM() 中的乘法运算符 * 之前添加一个反斜杠 (\),否则我无法发布答案。测试查询时删除反斜杠。

    【讨论】:

    • 为什么大家都写代码要乘以-1?计算机可以快得多从零中减去。
    • @WarrenT - 有没有我们可以查看的性能比较?
    • 它对CPU指令的基本理解。编写一个循环将 int x = x * -1 相乘一百万次,另一个循环将 int y = 0 - y 相减一百万次。在 C 或其他语言中,您应该会看到很大的不同。在这样的 SQL 查询中,整体影响是微不足道的。所以一方面担心它没有什么意义,另一方面我们(作为一个职业)为什么不应该习惯性地选择更简单、更有效的选择呢?
    • 虽然确实如此,但这可能是一个易于阅读的问题,尤其是在增加 SQL 语句的复杂性时。我在一个小型模型 515 上的一个 1.9M 行表上运行 SQLRPGLE 模块中的两个表单,看看它有多大的不同。对于 (x = x * -1) 形式,三次运行的平均时间为 51.031 秒,对于 (y = 0 - y),平均时间为 46.325 秒。在大多数情况下,差异可能不够显着。 SQL 背后的编译代码量往往会掩盖数学的微小代码。 (顺便说一句,对于简单的数学循环,差异也几乎一样小。)
    【解决方案4】:

    只要你能像这样分组,那么这个计算应该比乘法快。 (为什么人们总是这样做?)它还会忽略任何不是“A”或“S”的行。只要这是一个罕见的事件(如果有的话),那么在这种情况下处理它应该更快,而不是在 WHERE 子句中执行额外的测试。

    SELECT ITEM, 
           SUM(case ADJUST_TYPE 
                 when 'A' then ADJUST_QTY 
                 when 'S' then 0 - ADJUST_QTY
                 else null 
              end) as tot_qty,
           INV_SOURCE, 
           INV_DEST,
           WAREHOUSE,
           VENDORASN 
      FROM INV_ADJUSTMENT 
      GROUP BY ITEM, INV_SOURCE, INV_DEST, WAREHOUSE, VENDORASN
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-26
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多