SQL聚合函数查询不生成预期结果

时间:2014-07-08 20:10:22

标签: sql sql-server group-by aggregate-functions

以下是我的查询,要经过大约一百万行来计算MTBUR(非计划修复前的平均时间):

DECLARE @BeginDate date = '01-01-2013', 
        @EndDate date = '12-31-2013'
BEGIN
SELECT H.AutoType, 
COALESCE(((SUM(H.Hours))/(CASE WHEN R.ReceivedDate BETWEEN @BeginDate AND @EndDate THEN COUNT(R.Confirmed) END)), SUM(H.Hours)) AS 'MTBUR'
FROM Hours H
INNER JOIN Repair R
ON H.SN = R.SN 
WHERE (R.Confirmed NOT LIKE 'C%' AND R.Confirmed NOT LIKE 'O%')
AND (H.Date BETWEEN @BeginDate AND @EndDate) 
GROUP BY H.AutoType, 
R.ReceivedDate
END

以下是两种类型的示例结果:

Type | MTBUR
------------
a    | value
a    | value
a    | value
b    | value
b    | value
b    | value

我希望我的结果看起来像这样:

Type | MTBUR
------------
a    | value
b    | value

为什么要多次对同一类型进行分组。我想每种类型只有1个值。

另外,为什么DBMS让我也按ReceivedDate分组?我觉得这种感觉搞砸了我的结果。有什么建议吗?

以下是我的CREATE TABLE:

CREATE TABLE [dbo].[acss_hours](
    [hoursId] [uniqueidentifier] NOT NULL,
    [name] [nvarchar](100) NULL,
    [Type] [nvarchar](100) NULL,
    [SN] [nvarchar](100) NULL,
    [Reg] [nvarchar](100) NULL,
    [Hours] [float] NULL,
    [Date] [datetime] NULL)

CREATE TABLE [dbo].[repair](
    [repairId] [uniqueidentifier] NOT NULL,
[Part] [nvarchar](100) NULL,
    [Customer] [nvarchar](100) NULL,
    [AutoType] [nvarchar](100) NULL,
    [ReceivedDate] [datetime] NULL,
    [Confirmed] [nvarchar](100) NULL,
    [Company] [nvarchar](100) NULL,
    [Reg] [nvarchar](100) NULL,
    [Manu] [nvarchar](100) NULL,
    [SN] [nvarchar](100) NULL)

4 个答案:

答案 0 :(得分:2)

你是对的,添加ReceivedDate会搞砸你的结果。对于RecievedDate,每种类型都会获得一行。

SQL Server如果强制您将RecievedDate添加到组中,因为您在select子句中使用它。当SQL Server处理每个AutoType时,它应该使用什么ReceivedDate?每个AutoType有多个ReceivedDates。它需要通过将每个单独的ReceivedDate添加到组中来使用它,或者它可以使用聚合函数(如min或max)来选择其中一个RecievedDates。

您希望查询如何处理它?<​​/ p>

我认为你应该把你的案子包装在COUNT中。

COUNT(CASE WHEN R.ReceivedDate BETWEEN @BeginDate AND @EndDate 
THEN R.Confirmed ELSE 0 END)

答案 1 :(得分:1)

您需要在组中包含计算中的R.ReceivedDate,因为您正在使用between语句评估列。它与包含select中的列相同。基本上,选择行中没有聚合函数的任何列都需要在组中。

答案 2 :(得分:0)

您必须使用关键字DISTINCT

如此有效,你可以这样查询:

DECLARE @BeginDate date = '01-01-2013', 
        @EndDate date = '12-31-2013'
BEGIN
SELECT       DISTINCT H.AutoType, 
             COALESCE(((SUM(H.Hours))/(CASE WHEN R.ReceivedDate BETWEEN @BeginDate AND @EndDate THEN COUNT(R.Confirmed) END)), SUM(H.Hours)) AS 'MTBUR'

FROM         Hours H
INNER JOIN   Repair R ON H.SN = R.SN 
WHERE        (R.Confirmed NOT LIKE 'C%' AND R.Confirmed NOT LIKE 'O%')
AND          (H.Date BETWEEN @BeginDate AND @EndDate) 
GROUP BY     H.AutoType, R.ReceivedDate
END

希望这有帮助!!!

答案 3 :(得分:0)

我没有让我在评论中发布此内容。尝试内部查询:

SELECT H.AutoType, COALESCE(((SUM(H.Hours))/(SUM(x.CountConfirmed))), SUM(H.Hours)) AS 'MTBUR'
FROM 
    (SELECT H.AutoType, CASE WHEN R.ReceivedDate BETWEEN @BeginDate AND @EndDate THEN 1 ELSE 0 END AS CountConfirmed
    FROM Hours H
    INNER JOIN Repair R
    ON H.SN = R.SN 
    WHERE (R.Confirmed NOT LIKE 'C%' AND R.Confirmed NOT LIKE 'O%')
    AND (H.Date BETWEEN @BeginDate AND @EndDate)) x
JOIN Hours H
ON H.AutoType = x.AutoType
WHERE (H.Date BETWEEN @BeginDate AND @EndDate) 
GROUP BY H.AutoType