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

次のクエリは、すべての結果を時間別にグループ化します。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 に答える
0

実際にあなたの質問に答えるには、これらの条件が where 句に必要なようです。また、タグが示唆するように、MySQL ではなく、SQL-Server 構文に非常によく似ています。

これは非常に非効率的であることにも注意してください。

    (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 の結果セットを返すことがデータを処理する最善の方法であるとは想像できません。1 時間ごとのカウントが必要な場合、時間を列として使用し、1 つのクエリを実行して 1 つのデータセットを返すのは意味がありませんか?

例えば

| 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 に答える