正如本论坛其他地方所讨论的那样(例如here),人们可以使用MySQL中的变量来模拟MS SQL Server中的row_number()over ...(by by order by ...)功能。例如,像这样的代码:
SELECT
col1,
col2,
ROW_NUMBER() OVER (PARTITION BY col1, col2 ORDER BY col3 DESC) AS rowNum
FROM Table1
可以在MySQL中实现:
SELECT
@rowNum :=
CASE
WHEN col1<>@col1 OR col2<>@col2 THEN 1
ELSE @rowNum+1
END rowNum
, @col1 := col1 col1
, @col2 := col2 col2
FROM
(SELECT @col1 := 'xxx', @col2 := 'yyy', @rowNum := 0) a,
(SELECT col1, col2, col3 FROM Table1 ORDER BY col1, col2, col3 DESC) b
虽然这很快(因为它避免了自我加入),但是我对将它投入生产犹豫不决,因为它对查询执行计划做出了详细的假设,这可能是也可能不是可移植的。特别是,它假定:
1)表'b'的行由外部查询
按其排序顺序处理2)外部查询的列从左到右计算(即rowNum - &gt; col1 - &gt; col2。
这些假设似乎打破了我习惯的SQL语法的常规抽象。此外,此查询要求程序员确保表1中不存在他/她为col1和col2提供的初始值。同样,在我看来,这是糟糕的设计。这让我想到了一个相关的问题,这是后一种形式(使用变量)ANSI SQL兼容(92或99),还是MySQL的一个特性?确定给定语法是否是ANSI SQL投诉的确定来源是什么?您是否觉得足够舒适地将第二个版本投入生产?
答案 0 :(得分:0)
不,MySQL解决方案不是标准SQL。 MySQL用户变量是ANSI / ISO SQL的扩展。
SQL-99 Complete, Really是一个免费的在线资源,以人类可读的方式描述SQL规范。它是一个在线版本,希望在其作者的许可下发布the book by the same name。
但是,我不知道SQL:2003或更高版本的类似资源。你必须purchase the specification documents from ISO。它们并不便宜,而且阅读干燥。
恕我直言,试图将自己限制在100%可移植的SQL并且符合语言抽象的限制。例如,尝试查找单个SQL数据类型,它在所有RDBMS品牌中实现完全相同,并且与语言规范完全匹配。我还没找到。