我在此表中存储营业时间。企业可以在同一天开设多个营业时间的关闭时间可以在当天的午夜之后。

CREATE TABLE [Process].[OpeningHours](
    [openinghoursid] [int] IDENTITY(1,1) NOT NULL,
    [businessid] [int] NOT NULL,
    [daynumber] [int] NOT NULL,
    [opentime] [time](7) NOT NULL,
    [duration] [int] NOT NULL,
    [closetime]  AS (dateadd(minute,[duration],[opentime])
)

该表中的样本数据包括:
INSERT [Process].[OpeningHours]
([openinghoursid], [businessid], [daynumber], [opentime], [duration])
VALUES (79, 18, 2, CAST(N'12:00:00' AS Time), 165),
       (80, 18, 2, CAST(N'18:00:00' AS Time), 240),
       (81, 18, 3, CAST(N'12:00:00' AS Time), 165),
       (82, 18, 3, CAST(N'18:00:00' AS Time), 240),
       (83, 18, 4, CAST(N'12:00:00' AS Time), 165),
       (84, 18, 4, CAST(N'18:00:00' AS Time), 240),
       (85, 18, 5, CAST(N'12:00:00' AS Time), 165),
       (86, 18, 5, CAST(N'18:00:00' AS Time), 240),
       (87, 18, 6, CAST(N'12:00:00' AS Time), 165),
       (88, 18, 6, CAST(N'18:00:00' AS Time), 300),
       (89, 18, 7, CAST(N'12:00:00' AS Time), 165),
       (90, 18, 7, CAST(N'18:00:00' AS Time), 600),
       (91, 18, 1, CAST(N'12:00:00' AS Time), 180);

现在,我想创建一个函数,该函数将在业务当前处于打开或关闭状态时返回。
CREATE FUNCTION [Process].[ufnIsSpaceOpen](@businessid int)
RETURNS BIT
AS
BEGIN
    DECLARE @currentdatetime DATETIME = GETDATE();
    DECLARE @dayofweek INT = DATEPART(dw,@currentdatetime);
    DECLARE @currentdate DATETIME = CONVERT(DATE, @currentdatetime);
    DECLARE @isopen BIT;

    SELECT @isopen = COUNT(*)
    FROM Process.OpeningHours
    WHERE
    daynumber = @dayofweek
    AND businessid = @businessid
    AND
    (
        @currentdatetime >= @currentdate + CONVERT(DATETIME, opentime)

        AND

        @currentdatetime <=
            CASE
                WHEN closetime < '00:00:00' THEN @currentdate + CONVERT(DATETIME, closetime)
                ELSE DATEADD(DAY,1,@currentdate) + CONVERT(DATETIME, closetime)
            END
    );

    RETURN @isopen;

END;

GO

我正在使用COUNT()来查看是否有任何行符合条件,如果0匹配则意味着它是关闭的,如果COUNT()大于0则它是打开的。当关闭时间在同一天之内时,此方法起作用,但是,当关闭时间在午夜之后或当前时间在午夜之后,则不起作用。

知道我该如何解决吗?

编辑:谢谢您的所有答复。最后,我继续使用@DenisRubashkin的解决方案。对于任何有兴趣的人,这是我使用的最终功能:
CREATE FUNCTION [Process].[ufnIsSpaceOpen](@businessid int)
RETURNS BIT
AS
BEGIN


    DECLARE @isopen BIT;
    DECLARE @Date DATETIME = GETDATE();

    SELECT @isopen = COUNT(*)
    FROM
    (
        SELECT (CAST(CAST(@Date AS DATE) AS DATETIME) + CAST(h.opentime AS DATETIME)) AS Opened,
            DATEADD(mi, h.duration, (CAST(CAST(@Date AS DATE) AS DATETIME) + CAST(h.opentime AS DATETIME))) AS Closed
        FROM Process.OpeningHours h
        WHERE h.daynumber = DATEPART(dw, @Date)
        AND businessid = @businessid

        UNION

        SELECT (CAST(DATEADD(day, -1, CAST(@Date AS DATE)) AS DATETIME) + CAST(h.opentime AS DATETIME)) AS Opened,
            DATEADD(mi, h.duration, (CAST(DATEADD(day, -1, CAST(@Date AS DATE)) AS DATETIME) + CAST(h.opentime AS DATETIME))) AS Closed
        FROM Process.OpeningHours h
        WHERE h.daynumber = CASE WHEN DATEPART(dw, @Date) = 1
                                 THEN 7
                                 ELSE DATEPART(dw, @Date) - 1
                                 END
        AND businessid = @businessid
    ) w
    WHERE @Date BETWEEN Opened AND Closed

    RETURN @isopen;

END;

最佳答案

CREATE TABLE #OpeningHours(
    [openinghoursid] int,
    [businessid] int NOT NULL,
    [daynumber] int NOT NULL,
    [opentime] time NOT NULL,
    [duration] int NOT NULL,
)

INSERT #OpeningHours
VALUES (79, 18, 2, CAST(N'12:00:00' AS Time), 165),
       (80, 18, 2, CAST(N'18:00:00' AS Time), 240),
       (81, 18, 3, CAST(N'12:00:00' AS Time), 165),
       (82, 18, 3, CAST(N'18:00:00' AS Time), 240),
       (83, 18, 4, CAST(N'12:00:00' AS Time), 165),
       (84, 18, 4, CAST(N'18:00:00' AS Time), 240),
       (85, 18, 5, CAST(N'12:00:00' AS Time), 165),
       (86, 18, 5, CAST(N'18:00:00' AS Time), 240),
       (87, 18, 6, CAST(N'12:00:00' AS Time), 165),
       (88, 18, 6, CAST(N'18:00:00' AS Time), 300),
       (89, 18, 7, CAST(N'12:00:00' AS Time), 165),
       (90, 18, 7, CAST(N'18:00:00' AS Time), 600),
       (91, 18, 1, CAST(N'12:00:00' AS Time), 180);

DECLARE @Date   DATETIME

SELECT @Date = GETDATE()

SELECT COUNT(*)
FROM
(
    SELECT (CAST(CAST(@Date AS DATE) AS DATETIME) + h.opentime) AS Opened,
        DATEADD(mi, h.duration, (CAST(CAST(@Date AS DATE) AS DATETIME) + h.opentime)) AS Closed
    FROM #OpeningHours h
    WHERE h.daynumber = DATEPART(dw, @Date)

    UNION

    SELECT (CAST(DATEADD(day, -1, CAST(@Date AS DATE)) AS DATETIME) + h.opentime) AS Opened,
        DATEADD(mi, h.duration, (CAST(DATEADD(day, -1, CAST(@Date AS DATE)) AS DATETIME) + h.opentime)) AS Closed
    FROM #OpeningHours h
    WHERE h.daynumber = CASE WHEN DATEPART(dw, @Date) = 1
                             THEN 7
                             ELSE DATEPART(dw, @Date) - 1
                             END
) w
WHERE @Date BETWEEN Opened AND Closed

DROP TABLE #OpeningHours

关于sql - 了解当前是否在T-SQL中营业,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43114296/

10-09 05:33