SQL 和聚合问题

Sea*_*rey 7 sql-server aggregate t-sql

有了这个查询:

SELECT SUM(qty) AS sumQty,
       cnetprodid
FROM   quoteitem
WHERE  ordered = 1
       AND sageSOPOrderReturnLineID IS NOT NULL
       AND LEN(LTRIM(RTRIM(cnetprodid))) > 0
       AND cnetprodid LIKE 'S%'
       AND price > 10
       AND created > DATEADD(MONTH, -3, GETDATE())
GROUP  BY cnetprodid
ORDER  BY SUM(qty) DESC 
Run Code Online (Sandbox Code Playgroud)

每个产品我得到一排,顶排有 294 个 assumQty和 'S10381902' 作为cnetprodid

输入此查询:

SELECT SUM(qty) AS sumQty,
       p.ProdID,
       p.CatID
FROM   quoteitem
       INNER JOIN cds_prod AS p
         ON p.ProdID COLLATE Latin1_General_CI_AS = cnetprodid
       INNER JOIN cds_atr AS a
         ON a.ProdID COLLATE Latin1_General_CI_AS = p.ProdID
       INNER JOIN lan_cat_sections AS c
         ON c.attID = a.atrID
             OR ( LEN(ISNULL(c.attID, '')) = 0
                  AND c.cat_id LIKE p.CatID + '%' )
                AND ( ( c.[include] = 0
                        AND a.valID NOT IN (SELECT Value
                                            FROM   Split(c.valID, ',')) )
                       OR ( c.[include] = 1
                            AND a.valID IN (SELECT Value
                                            FROM   Split(c.valID, ',')) ) )
WHERE  ordered = 1
       AND sageSOPOrderReturnLineID IS NOT NULL
       AND LEN(LTRIM(RTRIM(cnetprodid))) > 0
       AND cnetprodid LIKE 'S%'
       AND price > 10
       AND created > DATEADD(MONTH, -3, GETDATE())
GROUP  BY p.ProdID,
          p.CatID,
          a.prodID
HAVING SUM(qty) > 10
ORDER  BY SUM(qty) DESC 
Run Code Online (Sandbox Code Playgroud)

我为每个产品返回一行,但现在带有“S10381902”的行作为ProdID列的数字为 8820 sumQty

我想要的只是上个季度销售了多少产品的数字,对销售量少于 10 件的产品不感兴趣,因此是HAVING部分。

COLLATE之所以存在,是因为这些表来自不同的数据库;一个在SQL_Latin1_General_CP1_CI_AS,另一个数据库在Latin1_General_CI_AS

小提琴:http ://sqlfiddle.com/#!3/ce1ed/4

db2*_*db2 5

可能的问题是,通过连接到这些附加表,quoteitem 中的行在中间结果中出现不止一次。也就是说,您有时会进行一对多连接。SQL Server 然后顺从地多次总结这些行。这是一个很容易犯的错误。

简单的解决方法是在执行任何一对多连接之前执行聚合计算。它可能看起来像这样。

SELECT q.sumQty,
       p.ProdID,
       p.CatID
FROM (
        SELECT ProdID, SUM(qty) AS sumQty, ...other columns...
        FROM quoteitem
        GROUP BY ProdID
        HAVING SUM(qty) > 10
    ) q
       INNER JOIN cds_prod AS p
         ON p.ProdID COLLATE Latin1_General_CI_AS = cnetprodid
       INNER JOIN cds_atr AS a
         ON a.ProdID COLLATE Latin1_General_CI_AS = p.ProdID
       INNER JOIN lan_cat_sections AS c
         ON c.attID = a.atrID
             OR ( LEN(ISNULL(c.attID, '')) = 0
                  AND c.cat_id LIKE p.CatID + '%' )
                AND ( ( c.[include] = 0
                        AND a.valID NOT IN (SELECT Value
                                            FROM   Split(c.valID, ',')) )
                       OR ( c.[include] = 1
                            AND a.valID IN (SELECT Value
                                            FROM   Split(c.valID, ',')) ) )
WHERE  ordered = 1
       AND sageSOPOrderReturnLineID IS NOT NULL
       AND LEN(LTRIM(RTRIM(cnetprodid))) > 0
       AND cnetprodid LIKE 'S%'
       AND price > 10
       AND created > DATEADD(MONTH, -3, GETDATE())
GROUP  BY p.ProdID,
          p.CatID,
          a.prodID
ORDER  BY q.sumQty DESC 
Run Code Online (Sandbox Code Playgroud)