简体   繁体   English

将MSSQL转换为MySQL

[英]Converting MSSQL to MySQL

Hye, I'm trying to convert a MSSQL query over to MYSQL and it's causing me issues. Hye,我正在尝试将MSSQL查询转换为MYSQL,这导致了我的问题。 This is beyond my current comfort zone. 这超出了我当前的舒适范围。 Below is my current query. 以下是我当前的查询。

WITH n AS ( 
  SELECT n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n) /* create a numbers table with 10 rows */ 
) 
, d AS ( /* Create a table with a row for each day in the date range */ 
         /* Use cross join to increase the rows in this table and then use top() to only return the rows we need */ 
   SELECT top (datediff(day, '2017-07-04', '2018-03-02')+1) 
   SessionDate = convert(datetime,dateadd(day,row_number() over(order by (select 1))-1,'2017-07-04')) 
   FROM n AS ten 
   CROSS JOIN n AS hundred /* cross join the numbers table to create 100 rows */ 
   CROSS JOIN n AS thousand /* cross join the numbers table to create 1,000 rows */ 
   CROSS JOIN n AS tenK /* cross join the numbers table to create 10,000 rows */ 
   CROSS JOIN n AS hundredK /* cross join the numbers table to create 100,000 rows */ 
   ORDER BY SessionDate 
) 
, h as ( /* add time ranges to date table */ 
    SELECT SessionDate, StartDateTime = dateadd(hour,v.s,SessionDate), EndDateTime = dateadd(hour,v.e,SessionDate), v.point 
    FROM d 
    CROSS APPLY (values 
       (0,12,'morning') 
       ,(12,17,'afternoon') 
       ,(17,24,'evening') 
    ) 
    v (s,e,point) 
) 
SELECT *
FROM h

It's using a numbers table and splitting out the dates into different time frames. 它使用数字表并将日期分为不同的时间范围。 Below is an example of the result set 以下是结果集的示例

SessionDate             | StartDateTime           | EndDateTime             | Point
2017-07-04 00:00:00.000 | 2017-07-04 00:00:00.000 | 2017-07-04 12:00:00.000 | morning
2017-07-04 00:00:00.000 | 2017-07-04 12:00:00.000 | 2017-07-04 17:00:00.000 | afternoon
2017-07-04 00:00:00.000 | 2017-07-04 17:00:00.000 | 2017-07-05 00:00:00.000 | evening
2017-07-05 00:00:00.000 | 2017-07-05 00:00:00.000 | 2017-07-05 12:00:00.000 | morning
2017-07-05 00:00:00.000 | 2017-07-05 12:00:00.000 | 2017-07-05 17:00:00.000 | afternoon
2017-07-05 00:00:00.000 | 2017-07-05 17:00:00.000 | 2017-07-06 00:00:00.000 | evening
2017-07-06 00:00:00.000 | 2017-07-06 00:00:00.000 | 2017-07-06 12:00:00.000 | morning
2017-07-06 00:00:00.000 | 2017-07-06 12:00:00.000 | 2017-07-06 17:00:00.000 | afternoon
2017-07-06 00:00:00.000 | 2017-07-06 17:00:00.000 | 2017-07-07 00:00:00.000 | evening

The query is too clever - it uses a CTE to generate a sequence of numbers instead of a calendar table, it uses CROSS APPLY to generate hours instead of using a lookup table for hours and names. 该查询太聪明了-它使用CTE生成数字序列而不是日历表,它使用CROSS APPLY生成小时数,而不是使用查找表来输入小时数和名称。 The resulting execution plan will be bad . 最终的执行计划会很糟糕

A very simple calendar table and a 'Sessions` table will allow you to create a far simpler T-SQL query, eg : 一个非常简单的日历表和一个“会话”表将使您可以创建一个更简单的T-SQL查询,例如:

CREATE TABLE Calendar (Date date primary key not null)
GO
--Omit code to fill the calendar
CREATE TABLE Sessions (StartTime int,EndTime int, Name nvarchar(20))
GO
insert into Sessions (StartTime,EndTime,Name)
VALUES
(0,12,'morning'),
(12,17,'afternoon'),
(17,24,'evening') 


select Date as SessionDate,
    dateadd(hour,StartTime,Date) as StartTime,
    dateadd(hour,EndTime,Date) as EndTimeTime,
    Name
from Calendar,Sessions
where Date between @startDate and @endDate

The range query will be very fast because the Date column is indexed. 范围查询将非常快,因为“ Date列已建立索引。 The execution plan will simply return all applicable date rows and combine them with the Session rows. 执行计划将仅返回所有适用的日期行,并将它们与会话行合并。

This can be easily converted to MySQL's dialect, eg by using DATE_ADD instead of DATEADD 可以轻松地将其转换为MySQL的方言,例如,使用DATE_ADD而不是DATEADD

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

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