如何在特定的时间间隔内正确地按日期时间列进行分组?

发布于 2024-12-25 13:56:51 字数 2575 浏览 1 评论 0原文

我正在 MSSQL 中创建一个存储过程,我想按间隔天对结果进行分组,但我不确定这是否正确:(

这是一部分)

    INSERT @Results
    (
        [Day],
        [Month],
        [Year],
        [Result]
    )
    SELECT
        DATEPART(DD, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(MM, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(YY, DATEADD(MI, @GmtOffset, EventDate)),
        Result = CASE WHEN @Metric = 'Take Rate' THEN NULL ELSE COUNT(*) END
    FROM BundleEvent
    WHERE BundleEventTypeId = CASE WHEN @Metric = 'Take Rate' THEN @TypeTakeId ELSE @BundleEventTypeId END
        AND EventDate >= @StartTime AND EventDate <= @EndTime
    GROUP BY
        DATEPART(YY, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(MM, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(DD, DATEADD(MI, @GmtOffset, EventDate))

我担心它最终会按日期对数据进行分组年或月并不重要。有谁知道我这样做是否正确? EventDate 是我想要按日期间隔进行GROUP BYDateTime 字段。

谢谢

编辑: 这是正确的方法,简单的格式交换...有时我需要更多咖啡。

INSERT @Results
(
    [Date],
    [Result]
)
SELECT
    CAST(DATEADD(MI, @GmtOffset, BundleEvent.EventDate) AS DATE),
    Result = CASE WHEN @Metric = 'Take Rate' THEN 0 ELSE COUNT(*) END
FROM dbo.BundleEvent WITH (NOLOCK)
JOIN dbo.BundleUser WITH (NOLOCK)
    ON BundleEvent.BundleId = BundleUser.BundleId
JOIN dbo.Bundle WITH (NOLOCK)
    ON BundleEvent.BundleId = Bundle.BundleId
WHERE BundleEvent.EventDate >= @StartTimeGmt AND BundleEvent.EventDate <= @EndTimeGmt
    AND BundleEvent.BundleEventTypeId = CASE WHEN @Metric = 'Take Rate' THEN @TypeTakeId ELSE @BundleEventTypeId END
    AND BundleUser.UserId = CASE WHEN @UserId IS NULL THEN BundleUser.UserId ELSE @UserId END
    AND Bundle.BundleType = 1
GROUP BY
    CAST(DATEADD(MI, @GmtOffset, BundleEvent.EventDate) AS DATE)

然后我与格式交换进行了子比较:

            CAST(
                (SELECT COUNT(*)
                FROM dbo.BundleEvent WITH (NOLOCK)
                JOIN dbo.BundleUser WITH (NOLOCK)
                    ON BundleEvent.BundleId = BundleUser.BundleId
                JOIN dbo.Bundle WITH (NOLOCK)
                    ON BundleEvent.BundleId = Bundle.BundleId
                WHERE CAST(DATEADD(MI, @GmtOffset, BundleEvent.EventDate) AS DATE) = [Date]
                AND BundleEvent.BundleEventTypeId = @TypeTakeId
                AND BundleUser.UserId = CASE WHEN @UserId IS NULL THEN BundleUser.UserId ELSE @UserId END
                AND Bundle.BundleType = 1)
                AS DECIMAL(5,2)

因此本质上查询是正确匹配并使用新格式的。

I am making a stored procedure in MSSQL and I want to group my results by the interval day, I am unsure if this is correct though:

(this is a portion)

    INSERT @Results
    (
        [Day],
        [Month],
        [Year],
        [Result]
    )
    SELECT
        DATEPART(DD, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(MM, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(YY, DATEADD(MI, @GmtOffset, EventDate)),
        Result = CASE WHEN @Metric = 'Take Rate' THEN NULL ELSE COUNT(*) END
    FROM BundleEvent
    WHERE BundleEventTypeId = CASE WHEN @Metric = 'Take Rate' THEN @TypeTakeId ELSE @BundleEventTypeId END
        AND EventDate >= @StartTime AND EventDate <= @EndTime
    GROUP BY
        DATEPART(YY, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(MM, DATEADD(MI, @GmtOffset, EventDate)),
        DATEPART(DD, DATEADD(MI, @GmtOffset, EventDate))

My fear is it is ultimately going to group the data by the date where the year or month do not matter. Does anyone know if I am doing this correctly? EventDate is the DateTime field that I want to do a GROUP BY on by interval of day.

Thanks

EDIT:
This is the correct way, a simple format exchange... sometimes I need more coffee.

INSERT @Results
(
    [Date],
    [Result]
)
SELECT
    CAST(DATEADD(MI, @GmtOffset, BundleEvent.EventDate) AS DATE),
    Result = CASE WHEN @Metric = 'Take Rate' THEN 0 ELSE COUNT(*) END
FROM dbo.BundleEvent WITH (NOLOCK)
JOIN dbo.BundleUser WITH (NOLOCK)
    ON BundleEvent.BundleId = BundleUser.BundleId
JOIN dbo.Bundle WITH (NOLOCK)
    ON BundleEvent.BundleId = Bundle.BundleId
WHERE BundleEvent.EventDate >= @StartTimeGmt AND BundleEvent.EventDate <= @EndTimeGmt
    AND BundleEvent.BundleEventTypeId = CASE WHEN @Metric = 'Take Rate' THEN @TypeTakeId ELSE @BundleEventTypeId END
    AND BundleUser.UserId = CASE WHEN @UserId IS NULL THEN BundleUser.UserId ELSE @UserId END
    AND Bundle.BundleType = 1
GROUP BY
    CAST(DATEADD(MI, @GmtOffset, BundleEvent.EventDate) AS DATE)

Then I do a sub compare with the format exchange:

            CAST(
                (SELECT COUNT(*)
                FROM dbo.BundleEvent WITH (NOLOCK)
                JOIN dbo.BundleUser WITH (NOLOCK)
                    ON BundleEvent.BundleId = BundleUser.BundleId
                JOIN dbo.Bundle WITH (NOLOCK)
                    ON BundleEvent.BundleId = Bundle.BundleId
                WHERE CAST(DATEADD(MI, @GmtOffset, BundleEvent.EventDate) AS DATE) = [Date]
                AND BundleEvent.BundleEventTypeId = @TypeTakeId
                AND BundleUser.UserId = CASE WHEN @UserId IS NULL THEN BundleUser.UserId ELSE @UserId END
                AND Bundle.BundleType = 1)
                AS DECIMAL(5,2)

So in essence the query is matching up correctly and using a new format.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁人与我共长歌 2025-01-01 13:56:52

由于您没有使用 and 聚合(除了 Count(*)),您确定需要 GROUP BY 吗?使用 DISTINCT 将为所有匹配日期生成一个插入条目;也许类似于:

DECLARE @DATE_GMT datetime
SET @DATE_GMT=DATEADD(MI, @GmtOffset, EventDate)
INSERT @Results
(
    [Day],
    [Month],
    [Year],
    [Result]
)
SELECT DISTINCT
    DATEPART(DD, @DATE_GMT),
    DATEPART(MM, @DATE_GMT),
    DATEPART(YY, @DATE_GMT),
    Result = CASE WHEN @Metric = 'Take Rate' THEN NULL ELSE COUNT(*) END
FROM BundleEvent
WHERE BundleEventTypeId = CASE WHEN @Metric = 'Take Rate' THEN @TypeTakeId ELSE @BundleEventTypeId END
    AND EventDate Between @StartTime AND @EndTime

Since you are not using and aggregates (except Count(*), Are you sure you want a GROUP BY? Using DISTINCT will produce a single insert entry for all matching dates; perhaps something like:

DECLARE @DATE_GMT datetime
SET @DATE_GMT=DATEADD(MI, @GmtOffset, EventDate)
INSERT @Results
(
    [Day],
    [Month],
    [Year],
    [Result]
)
SELECT DISTINCT
    DATEPART(DD, @DATE_GMT),
    DATEPART(MM, @DATE_GMT),
    DATEPART(YY, @DATE_GMT),
    Result = CASE WHEN @Metric = 'Take Rate' THEN NULL ELSE COUNT(*) END
FROM BundleEvent
WHERE BundleEventTypeId = CASE WHEN @Metric = 'Take Rate' THEN @TypeTakeId ELSE @BundleEventTypeId END
    AND EventDate Between @StartTime AND @EndTime
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文