简体   繁体   English

在has子句中不存在的列上进行分组

[英]group by on a column not present in having clause

I have a simple SQL query with GROUP BY , HAVING and ORDER BY clauses. 我有一个简单的SQL查询,它带有GROUP BY,HAVING和ORDER BY子句。 The HAVING clause has some fields that I don't want in the GROUP BY , is that possible ? HAVING子句在GROUP BY中有一些我不需要的字段,可以吗? Because I have to group the data hourly , and I have a date field in the HAVING , so the grouping doesn't work properly. 因为我必须每小时对数据进行分组,并且HAVING中有一个日期字段,所以分组无法正常进行。 The code is: 代码是:

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

The following query groups all results by hour. 以下查询按小时将所有结果分组。 Why don't you want to have the CreatedDate in the GROUP BY? 您为什么不想在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;

To actually answer your question, It looks like you just want these conditions in the where clause. 要实际回答您的问题,似乎您只需要where子句中的这些条件。 It also looks very much like SQL-Server syntax, not MySQL as the tags suggest. 它也看起来非常像SQL-Server语法,而不是标签所暗示的MySQL。

It is also worth noting that this is very inefficient: 还值得注意的是,这是非常低效的:

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

using DATEPART on the column will not only force the function to evaluate for every row, it also removes the benefits of any index on the column. 在列上使用DATEPART不仅将强制函数对每一行进行求值,而且还消除了列上任何索引的好处。 This would be much better written as Createddate >= '20130227 00:00' AND CreatedDate < '20130227 01:00' . 写成Createddate >= '20130227 00:00' AND CreatedDate < '20130227 01:00'会更好。

In addition in each loop you executing for 2 hour periods which does not sound like the intended behaviour. 此外,在每个循环中,您执行2小时的周期听起来都不像预期的行为。

Finally I cannot imagine returning 24 results sets is the best way to deal with the data, If you want a count for each hour would it not make sense to have the hours as columns and execute one query and return one dataset? 最后,我无法想象返回24个结果集是处理数据的最佳方法,如果您希望每小时进行计数,那么将小时数作为列并执行一个查询并返回一个数据集就没有意义了吗?

eg 例如

| 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  |

In which case your query could be written as 在这种情况下,您的查询可以写为

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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM