SQL对计数求和会导致聚合函数错误

时间:2014-02-05 14:32:05

标签: sql sql-server aggregate-functions

我正在尝试减少报告运行的查询数量以获得特定结果。我已经把它放在那里,但是我不能把它带到我需要的地方。数据库来自仓库的订单拣选/包装系统。问题中的3个表是包装数据,用户数据和拣配数据。我需要的是一个人在一天中所有批次包装的总行数,但是数据库中没有存储行数。我可以从每个批次的选择表中的所有记录的计数中获得行数,但这不会被打包的人破坏。打包表包含基本信息,如Batch_Num,Cart_Num,Badge_Num,以及一些不适用于此问题的日期和错误跟踪。从这里,我可以得到每个用户的批次列表,我可以从选择表中提取每个用户的行数,但我需要为每个用户得到这些总和。

SELECT     t1.Badge_Num,
           t1.Batch_Num,
           t2.UserDescription,
           (SELECT COUNT(Batch_Num) AS lines
                FROM Pick WHERE (Batch_Num = t1.Batch_Num)) AS totallines
FROM       Pack AS t1 WITH (NOLOCK) 
                FULL OUTER JOIN JenX.dbo.Users AS t2 
                      ON t1.Badge_Num = t2.UserName  
WHERE      (t1.DateCreated BETWEEN '02/04/2014' AND '02/05/2014')
GROUP BY   t2.UserDescription, t1.Badge_Num, t1.Batch_Num
ORDER BY   t2.UserDescription, t1.Badge_Num

由于我还无法发布图片,我将输入我到达的结果。

Badge_Num        Batch_Num        UserDescription        TotalLines
99900001         93943            Joe User               40
99900001         93394            Joe User               58
99900001         93944            Joe User               58
99900001         93930            Joe User               110
99900001         94322            Joe User               77
99900001         94101            Joe User               86
99900001         94691            Joe User               68
99944444         93010            Tom Packer             15
99944444         93001            Tom Packer             99
99944444         92972            Tom Packer             30
99944444         93003            Tom Packer             52
99944444         92972            Tom Packer             15

这给了我一个来自每个用户的批次列表(黑名单,但它们都在那里),每个批次都有一个行数,但是对于我的生活,我无法将这些行汇总。我甚至不需要在此列出的批次#s,只需要用户名和总行数就可以了。任何建议都将不胜感激。

3 个答案:

答案 0 :(得分:1)

如果我理解正确,您希望修改此查询以从聚合中删除badge_num。你不能因为相关的子查询。试试这个:

SELECT     t1.Badge_Num,
           t2.UserDescription,
           COUNT(p.Batch_Num) AS totallines
FROM       Pack t1 WITH (NOLOCK) left outer join
           JenX.dbo.Users t2 
           ON t1.Badge_Num = t2.UserName left outer join
           Pick p
           on p.Batch_Num = t1.Batch_Num
WHERE      (t1.DateCreated BETWEEN '02/04/2014' AND '02/05/2014')
GROUP BY   t2.UserDescription, t1.Badge_Num
ORDER BY   t2.UserDescription, t1.Badge_Num;

full outer join条款取消了where的效果。

答案 1 :(得分:0)

SELECT  lines.Badge_Num,
        u.UserDescription,
        lines.Batches,
        totallines = lines.Lines
FROM    (   SELECT  pa.Badge_Num,
                    Batches = COUNT(DISTINCT pa.Batch_Num),
                    Lines = COUNT(*)
            FROM    dbo.Pack pa
                    JOIN dbo.Pick pic ON pa.Batch_Num = pic.Batch_Num
            WHERE pa.DateCreated BETWEEN '2014-02-04' AND '2014-02-05'
            GROUP BY pa.Badge_Num
        ) lines
        LEFT JOIN JenX.dbo.Users u ON lines.Badge_Num = u.UserName
ORDER BY UserDescription, Badge_Num;

编辑2014-02-05 10:11 +04 - 我根据接受的答案(但不是,有趣的是,实际问题)添加批次的数量是OP想要的

编辑2014-02-05 10:19 +04 - 我添加了dbo.Pick表,直到现在我都没注意到。糟糕!

答案 2 :(得分:0)

首先,我会使用CTE

重写您的查询
WITH    lines
          AS ( SELECT Batch_num
                   ,COUNT(*) AS lines
                FROM Pick
                GROUP BY Batch_num)
    SELECT t1.Badge_Num
           ,t1.Batch_Num
           ,t2.UserDescription
           ,l.lines AS totallines
        FROM Pack AS t1 WITH ( NOLOCK )
        LEFT OUTER JOIN lines AS l
            ON t1.Batch_Num = l.Batch_Num
        FULL OUTER JOIN JenX.dbo.Users AS t2
            ON t1.Badge_Num = t2.UserName
        WHERE ( t1.DateCreated BETWEEN '02/04/2014' AND '02/05/2014' )
获取SUM旁边的

您只需添加SUMGROUP BY子句

WITH    lines
          AS ( SELECT Batch_num
                   ,COUNT(*) AS lines
                FROM Pick
                GROUP BY Batch_num)
    SELECT t1.Badge_Num
           ,t1.Batch_Num
           ,t2.UserDescription
           ,SUM(l.lines) AS totallines
        FROM Pack AS t1 WITH ( NOLOCK )
        LEFT OUTER JOIN lines AS l
            ON t1.Batch_Num = l.Batch_Num
        FULL OUTER JOIN JenX.dbo.Users AS t2
            ON t1.Badge_Num = t2.UserName
        WHERE ( t1.DateCreated BETWEEN '02/04/2014' AND '02/05/2014' )
        GROUP BY t1.Badge_Num
           ,t1.Batch_Num
           ,t2.UserDescription
        ORDER BY t2.UserDescription
           ,t1.Badge_Num