Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重写MySQL的MS SQL查询_Mysql_Sql_Sql Server_Common Table Expression - Fatal编程技术网

重写MySQL的MS SQL查询

重写MySQL的MS SQL查询,mysql,sql,sql-server,common-table-expression,Mysql,Sql,Sql Server,Common Table Expression,不久前,一位用户发布了一个有趣的查询,该查询是为MS SQL编写的,它依赖于公共表表达式CTE。有人能告诉我们MySQL的查询是什么样子的吗 我包括了整个示例,它还创建了一个包含一些示例数据的临时表。我只是对MySQL的约会查询感兴趣。在查询下面,我发布了预期的输出 以下是原始帖子的链接: -问题的样本数据。 声明@预约表 [ID]bigint not null标识1,1,-主键。 [BookedDate]日期不为空,-约会日期。 [Time]time0不为空,-约会的开始时间。 [Durat

不久前,一位用户发布了一个有趣的查询,该查询是为MS SQL编写的,它依赖于公共表表达式CTE。有人能告诉我们MySQL的查询是什么样子的吗

我包括了整个示例,它还创建了一个包含一些示例数据的临时表。我只是对MySQL的约会查询感兴趣。在查询下面,我发布了预期的输出

以下是原始帖子的链接:

-问题的样本数据。 声明@预约表 [ID]bigint not null标识1,1,-主键。 [BookedDate]日期不为空,-约会日期。 [Time]time0不为空,-约会的开始时间。 [Duration]int not null-约会的长度(以分钟为单位)。 ; 插入@约会 [BookedDate]、[Time]、[Duration] 价值观 '2014-04-15', '09:00', 60, '2014-04-15', '10:00', 30, '2014-04-15', '17:00', 60, '2014-04-15', '18:30', 30; -@StartTime是办公室在所需日期打开的时间。 -@EndTime是办公室在所需日期关闭的时间。 -@Interval是分隔潜在约会时间的分钟数。 -@DesiredDate是请求预约的日期。 -@DesiredLength是请求的约会的长度,以分钟为单位。 声明@starttimetime0='09:00'; 声明@EndTime time0='21:00'; 声明@Interval int=30; 声明@DesiredDate='2014-04-15'; 声明@DesiredLength int=30; -鉴于上述数据,此CTE枚举@DesiredDate上的所有潜在时隙。 将[TimeSlotCTE]作为 -基本情况:一天中的第一个预约时段。 选择 [来源]=@StartTime, [To]=dateaddminute、@DesiredLength、@StartTime 联合所有 -递归案例:创建后续约会时段,只要这样做不会 -带我们过了办公室的关门时间。 选择 dateaddminute,@Interval,[From], dateaddminute,@Interval,[To] 从…起 [时隙] 哪里 dateaddminute,@Interval,[To][T].[From] 然后“否”或“是”结束 从…起 [TimeSlotCTE][T]; 输出

From        To          Available
09:00:00    09:30:00    No
09:30:00    10:00:00    No
10:00:00    10:30:00    No
10:30:00    11:00:00    Yes
11:00:00    11:30:00    Yes
11:30:00    12:00:00    Yes
12:00:00    12:30:00    Yes
12:30:00    13:00:00    Yes
13:00:00    13:30:00    Yes
13:30:00    14:00:00    Yes
14:00:00    14:30:00    Yes
14:30:00    15:00:00    Yes
15:00:00    15:30:00    Yes
15:30:00    16:00:00    Yes
16:00:00    16:30:00    Yes
16:30:00    17:00:00    Yes
17:00:00    17:30:00    No
17:30:00    18:00:00    No
18:00:00    18:30:00    Yes
18:30:00    19:00:00    No
19:00:00    19:30:00    Yes
19:30:00    20:00:00    Yes
20:00:00    20:30:00    Yes
20:30:00    21:00:00    Yes

谢谢大家!

这条评论太长了

您可以移动到MySQL 8+进行直接转换。MySQL现在支持常见的表表达式CTE和递归CTE。当然,MySQL约定的代码会改变,但总的来说是一样的


另一种方法是在两个数据库中使用数字表来构造约会开始。从性能的角度来看,这可能是一个好主意。

我是DBA MSSQL,因此我将您的问题视为挑战

我只是把CT和变量表转换成一个临时表,把dateadd转换成minute

试试这个,如果有用就告诉我

-- Sample data from the question.

CREATE TEMPORARY TABLE IF NOT EXISTS Appointment_TMP AS
(
    [ID] bigint not null identity(1, 1), -- Primary key.
    [BookedDate] date not null,          -- The date of the appointment.
    [Time] time(0) not null,             -- The start time of the appointment.
    [Duration] int not null              -- The length of the appointment in minutes.
)
insert Appointment_TMP
    ([BookedDate], [Time], [Duration])
values
    ('2014-04-15', '09:00', 60),
    ('2014-04-15', '10:00', 30),
    ('2014-04-15', '17:00', 60),
    ('2014-04-15', '18:30', 30);

-- @StartTime is the time the office opens on the desired date.
-- @EndTime is the time the office closes on the desired date.
-- @Interval is the number of minutes that separate potential appointment times.
-- @DesiredDate is the date on which an appointment is requested.
-- @DesiredLength is the length of the requested appointment in minutes.
declare @StartTime time(0) = '09:00';
declare @EndTime time(0) = '21:00';
declare @Interval int = 30;
declare @DesiredDate date = '2014-04-15';
declare @DesiredLength int = 30;

-- This CTE enumerates all potential timeslots on the @DesiredDate given the above data.
CREATE TEMPORARY TABLE IF NOT EXISTS TimeSlotCTE AS
(
    -- Base case: the first appointment slot of the day.
    select 
        @StartTime as From, 
        minute(@DesiredLength-@StartTime) as To

    union all

    -- Recursive case: create a subsequent appointment slot as long as doing so won't
    -- take us past the office's closing time.
    select
        minute(@Interval-From),
        minute( @Interval-To)
    from
        [TimeSlotCTE]
    where
        minute( @Interval-[To]) <= @EndTime
)

-- Finally, we simply select every time slot defined above for which there does not
-- yet exist an overlapping appointment on the requested date.
select
    [T].[From],
    [T].[To],
    [Available] = 
        case when exists 
        (
            select 1 from Appointment_TMP [A]
            where
                -- Forgot this line the first time around!
                [A].[BookedDate] = @DesiredDate and
                [A].[Time] < [T].[To] and
                minute(minute, [A].[Duration]-[A].[Time]) > [T].[From]
        )
        then 'No' else 'Yes' end
from
    [TimeSlotCTE] [T];