【问题标题】:How to SUM in JOIN, to avoid issue with two SUM in SELECT statement如何在 JOIN 中求和,以避免在 SELECT 语句中出现两个 SUM 的问题
【发布时间】:2015-02-19 02:10:17
【问题描述】:

我已经阅读了很多关于类似问题的帖子,但都没有找到解决方案,所以我发布了一个新问题。这两个特别解决了类似的问题:

SQL SELECT with multiple tables and SUM

How to write subquery inside the OUTER JOIN Statement

这是我拥有的代码的第一个版本以及它产生的问题。这是在 DB2 for iSeries 数据库中。我只是得到一个通用的ODBC error 1004,这意味着 SQL 很好,但数据库不喜欢代码的某些内容。我已经验证了表名和列名是正确的。

SELECT i.IMFGR || i.ICOLOR || i.IPATT Item, i.INAME DESC1, i.INAME2 DESC2, 
       i.IPOL1 PC1, i.IPOL2 PC2, i.IPOL3 PC3, SUM(s.JONHAN) QOH, i.IUNITS UM, 
       SUM(inv.INEXTP) Sales, i.IINVEN INV, i.ICCTR CC, i.ICLAS1 I1, i.IDISCD DDate, 
       i.ILPODT LOrder, i.IAVGC AVGC 
FROM QS36F.ITEM i
JOIN QS36F.ITEMSTK s
     ON i.IMFGR || i.ICOLOR || i.IPATT = s.JMFGR || s.JCOLOR || s.JPAT
        JOIN QS36F.INVOICED inv
     ON inv.INMFGR || inv.INCOLO || inv.INPATT = i.IMFGR || i.ICOLOR || i.IPATT
WHERE (i.IMFGR = '" & man & "') AND ((i.IPOL1 = 'SP') OR (i.IPOL2 = 'SP') OR 
      (i.IPOL3 = 'SP') OR (i.IPOL1 = 'DI') OR (i.IPOL2 = 'DI') OR (i.IPOL3 = 'DI'))
GROUP BY i.IMFGR || i.ICOLOR || i.IPATT, i.INAME, i.INAME2, i.IPOL1, i.IPOL2, i.IPOL3, 
         i.IUNITS, i.IINVEN, i.ICCTR, i.ICLAS1, i.IDISCD, i.ILPODT, i.IAVGC
ORDER BY i.IMFGR || i.ICOLOR || i.IPATT

这不起作用,因为它导致 SUM(s.JONHAN) QOH 被乘以多次,因此不准确。

在阅读了一些线程之后,看来我需要将第二个 SUM 放入 JOIN 语句中。但是,我仍然收到ODBC error 1004,所以我不确定我错过了什么。

SELECT i.IMFGR || i.ICOLOR || i.IPATT Item, i.INAME DESC1, i.INAME2 DESC2, 
       i.IPOL1 PC1, i.IPOL2 PC2, i.IPOL3 PC3, SUM(s.JONHAN) QOH, i.IUNITS UM, 
       inv.Sales, i.IINVEN INV, i.ICCTR CC, i.ICLAS1 I1, i.IDISCD DDate,
       i.ILPODT LOrder, i.IAVGC AVGC 
FROM QS36F.ITEM i
JOIN QS36F.ITEMSTK s
     ON i.IMFGR || i.ICOLOR || i.IPATT = s.JMFGR || s.JCOLOR || s.JPAT
LEFT OUTER JOIN (SELECT INMFGR || INCOLO || INPATT Item, SUM(INEXTP) Sales
                 FROM QS36F.INVOICED
                 GROUP BY INMFGR, INCOLO, INPATT) inv
                     ON inv.Item = i.IMFGR || i.ICOLOR || i.IPATT
WHERE (i.IMFGR = '" & man & "') AND ((i.IPOL1 = 'SP') OR (i.IPOL2 = 'SP') OR 
      (i.IPOL3 = 'SP') OR (i.IPOL1 = 'DI') OR (i.IPOL2 = 'DI') OR (i.IPOL3 = 'DI'))
GROUP BY i.IMFGR || i.ICOLOR || i.IPATT, i.INAME, i.INAME2, i.IPOL1, i.IPOL2, i.IPOL3, 
         i.IUNITS, i.IINVEN, i.ICCTR, i.ICLAS1, i.IDISCD, i.ILPODT, i.IAVGC
ORDER BY i.IMFGR || i.ICOLOR || i.IPATT

在添加第二个 SUMJOIN 语句之前,一切都很好。我可以在第二个JOIN 中对SELECT 进行查询,它会正常运行。

【问题讨论】:

  • 摘录:i.IMFGR = '" & man & "'表示这段代码很可能容易受到sql注入攻击。
  • 也许不是。如果上面是发送到 DB2 for i 的语句,那么它实际上是字符串 '" & man &"',单引号是字符串分隔符。 ||是连接运算符。 OTOH,如果上面是在 VB 中构建的字符串,其中 & 是连接运算符......那么是的,我同意你的看法。
  • Charles 指出连接 join 和 group 列不好的原因是它会迫使 db 完全忽略任何索引。换句话说,对于任何实际大小的桌子,它都会慢得离谱。这可能是它不开心的原因,因为你要求它做很多工作。

标签: sql join db2 ibm-midrange


【解决方案1】:

首先,这个:

JOIN QS36F.ITEMSTK s
     ON i.IMFGR || i.ICOLOR || i.IPATT = s.JMFGR || s.JCOLOR || s.JPAT

是个坏主意,应该是这样

JOIN QS36F.ITEMSTK s
     ON i.IMFGR = s.JMFGR
        and i.ICOLOR = s.JCOLOR 
        and i.IPATT =  s.JPAT

其次,我看不出有什么明显的错误。如果您可以查看为 ODBC 请求提供服务的 QZDASOINIT 作业的作业日志并报告 DB2 抛出的实际错误,将会有所帮助。

话虽如此,我更喜欢通用表表达式 (CTE),而不是嵌套表表达式 (NTE)

WITH inv as (SELECT INMFGR, INCOLO, INPATT, SUM(INEXTP) Sales
               FROM QS36F.INVOICED
              GROUP BY INMFGR, INCOLO, INPATT
             )
, s as (SELECT JMFGR, JCOLOR, JPAT, sum(JOHHAN) TotalOH
          FROM QS36F.ITEMSTK
         GROUP BY JMFGR, JCOLOR, JPAT
       )
SELECT i.IMFGR || i.ICOLOR || i.IPATT Item, i.INAME DESC1, i.INAME2 DESC2, 
       i.IPOL1 PC1, i.IPOL2 PC2, i.IPOL3 PC3, s.TotalOH QOH, i.IUNITS UM, 
       inv.Sales, i.IINVEN INV, i.ICCTR CC, i.ICLAS1 I1, i.IDISCD DDate,
       i.ILPODT LOrder, i.IAVGC AVGC 
FROM QS36F.ITEM i
JOIN s
      ON i.IMFGR = s.INMFGR
         and i.ICOLOR = s.INCOLOR 
         and i.IPATT =  s.INPATT
LEFT OUTER JOIN inv
       ON i.IMFGR = inv.JMFGR
            and i.ICOLOR = inv.JCOLOR 
            and i.IPATT =  inv.JPAT
WHERE (i.IMFGR = '" & man & "') AND ((i.IPOL1 = 'SP') OR (i.IPOL2 = 'SP') OR 
      (i.IPOL3 = 'SP') OR (i.IPOL1 = 'DI') OR (i.IPOL2 = 'DI') OR (i.IPOL3 = 'DI'))
ORDER BY i.IMFGR, i.ICOLOR, i.IPATT

【讨论】:

  • 您可能可以按单个列排序,而不是串联。特别是如果您不通过串联加入...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-19
  • 1970-01-01
  • 1970-01-01
  • 2011-12-14
  • 1970-01-01
相关资源
最近更新 更多