【发布时间】:2018-08-09 18:38:30
【问题描述】:
嘿,我正在尝试将 MSSQL 查询转换为 MYSQL,这给我带来了问题。这超出了我目前的舒适区。以下是我当前的查询。
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
它使用数字表并将日期分成不同的时间范围。下面是一个结果集的例子
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
【问题讨论】:
-
你输了。 MySQL 相当……在 SQL 特性方面受到限制。它没有窗口、排名或分析功能。排名通常使用相当丑陋的黑客或未记录的功能来模拟。例如,可以通过在 select 子句中增加 ... 变量来生成行号。
...,@rownum := @rownum + 1 AS rank -
MySql 的当前版本不支持Windowing Functions (
row_number())、CTEs 或lateral joins (APPLY),这里都用到了。如果可能的话,您必须完全重新编写此查询。 CTE 问题正在为下一个完整的 MySql 版本修复,但窗口函数和横向连接仍然存在,以及完全连接、物化视图等。IMO,MySql 并不是真正的“现代”关系数据库,并且没有已经有十多年了。如果你想免费/OSS,Postgresql 可能是一个更好的选择。 -
祝你好运。此查询中使用的大多数功能在 MySQL 中不存在。您不妨从头开始创建查询,而不是尝试将其转换为 MySQL 查询。没有
CTE,没有CROSS JOIN,没有OVER(),没有CROSS APPLY。 -
"MySQL 查询。没有 CTE,没有 CROSS JOIN,没有 OVER(),没有 CROSS APPLY" MySQL 支持 CROSS JOIN @Eric
-
@user2634794 您还可以创建一个 time 表,将小时与上午、下午等相匹配。之后,您只需在日历和时间之间创建笛卡尔积您想要的日期范围的表格。这将导致更简单和更快的查询
标签: mysql sql-server database-migration