0

我有一个带有 GROUP BY 、 HAVING 和 ORDER BY 子句的简单SQL查询。HAVING 子句在 GROUP BY 中有一些我不想要的字段,这可能吗?因为我必须每小时对数据进行分组,并且在 HAVING 中有一个日期字段,所以分组无法正常工作。代码是:

alter procedure [dbo].[sp_metadata_inflow]
@grp_name varchar(40) , @subgrp_name varchar(40)
as
begin
declare @i as int , @j as int,@k as int,@d as datetime , @m as datetime,@y as datetime;
set @d = datepart(day,'2012-12-13 10:54:55.000');
set @m = datepart(month,'2012-12-13 10:54:55.000');
set @y = datepart(YEAR,'2012-12-13 10:54:55.000');
set @i = 1;
set @j = @i - 1;
while (@i <=24)
begin
(SELECT  top 5 @i,
         ContactReason,
         @grp_name,
         @subgrp_name,
         COUNT(*)
 FROM   [ISRM].[dbo].[ITSM01ISRM]
 GROUP  BY ContactReason,datepart(day,CreatedDate),CurrentGroup,CurrentSubGroup
 HAVING (
         datepart(day,CreatedDate)= @d AND datepart(MONTH,CreatedDate)= @m
         AND datepart(year,CreatedDate) = @y AND datepart(hour,CreatedDate) <= @i
         AND datepart(hour,CreatedDate) >=@j
        )
        AND (CurrentGroup = @grp_name) AND (CurrentSubGroup = @subgrp_name)
);
set @i = @i + 1;
set @j =  @i -1;
end
end
go
4

2 回答 2

0

要实际回答您的问题,您似乎只希望在 where 子句中使用这些条件。它看起来也很像 SQL-Server 语法,而不是标签所暗示的 MySQL。

还值得注意的是,这是非常低效的:

    (datepart(day,CreatedDate)= @d 
AND datepart(MONTH,CreatedDate)= @m
AND datepart(year,CreatedDate) = @y 
AND datepart(hour,CreatedDate) <= @i 
AND datepart(hour,CreatedDate) >=@j ) 

在列上使用DATEPART不仅会强制函数对每一行进行评估,它还会消除列上任何索引的好处。这会更好写成Createddate >= '20130227 00:00' AND CreatedDate < '20130227 01:00'.

此外,在每个循环中,您执行 2 小时,这听起来不像预期的行为。

最后,我无法想象返回 24 个结果集是处理数据的最佳方式,如果您想要每小时计算一次,将小时作为列并执行一个查询并返回一个数据集是否没有意义?

例如

| ContactReason  | GroupName  | SubGroupName | 00:00 | 01:00 | 02:00 | 03:00 |.....| 23:00 |
|----------------+------------+--------------+-------+-------+-------+-------+.....+-------|
| Example Reason | Test Group | Sub Group    |   5   |   10  |    8  |    1  |.....|   14  |
| Another Reason | Test Group | Sub Group    |   3   |    1  |   13  |    8  |.....|   23  |

在这种情况下,您的查询可以写成

DECLARE @Date DATETIME = '20121213';

WITH Data AS
(       SELECT  ContactReason,
                GroupName = @grp_name,
                SubGroupName = @subgrp_name,
                CreatedHour = CAST(DATEADD(HOUR, DATEDIFF(HOUR, 0, Createddate), 0) AS TIME),
                [Value] = 1
        FROM    [ISRM].[dbo].[ITSM01ISRM] 
        WHERE   CurrentGroup = @grp_name
        AND     CurrentSubGroup = @subgrp_name
        AND     CreatedDate >= @Date
        AND     CreatedDate < DATEADD(DAY, 1, @Date)
)
SELECT  *
FROM    Data
        PIVOT
        (   COUNT(Value)
            FOR CreatedHour IN 
                (   [00:00], [01:00], [02:00], [03:00], [04:00], [05:00], 
                    [06:00], [07:00], [08:00], [09:00], [10:00], [11:00], 
                    [12:00], [13:00], [14:00], [15:00], [16:00], [17:00],
                    [18:00], [19:00], [20:00], [21:00], [22:00], [23:00]
        ) pvt;
于 2013-02-27T10:18:27.803 回答
0

以下查询按小时对所有结果进行分组。为什么不希望在 GROUP BY 中有 CreatedDate?

SELECT
    ContactReason,
    CurrentGroup,
    CurrentSubGroup,
    dateadd(hour, datediff(hour, 0, CreatedDate), 0),
    COUNT(1) 
FROM [ISRM].[dbo].[ITSM01ISRM] 
WHERE
    (CurrentGroup = @grp_name) AND (CurrentSubGroup = @subgrp_name)
GROUP BY 
    ContactReason,
    dateadd(hour, datediff(hour, 0, CreatedDate), 0),
    CurrentGroup,
    CurrentSubGroup;
于 2013-02-27T09:52:24.137 回答