1

正如本论坛其他地方(例如此处)所讨论的,可以使用 MySQL 中的变量来模拟 MS SQL Server 中的(按...排序...分区)功能的 row_number()。例如,这样的代码:

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 -> col1 -> col2。

这些假设似乎打破了我习惯的 SQL 语法的通常抽象。此外,此查询要求程序员确保他/她为 col1 和 col2 提供的初始值不存在于 Table1 中。同样,在我看来,这是一个糟糕的设计。这给我带来了一个相关的问题,后一种形式(使用变量)是否符合 ANSI SQL(92 或 99),还是 MySQL 的一个特性?确定给定语法是否符合 ANSI SQL 的明确来源是什么?您是否愿意将第二个版本投入生产?

4

1 回答 1

0

不,MySQL 解决方案不是标准 SQL。MySQL 用户变量是 ANSI/ISO SQL 的扩展。

SQL-99 Complete,Really是一个免费的在线资源,以人类可读的方式描述 SQL 规范。这是同名书籍的在线版本,希望在获得作者许可的情况下发布。

但是,我不知道 SQL:2003 或更高版本的类似资源。您必须从 ISO 购买规范文件。它们并不便宜,而且是枯燥的阅读。

恕我直言,试图将自己限制在 100% 可移植且符合语言抽象的 SQL 上太受限制了。例如,尝试找到在所有品牌的 RDBMS 中实现完全相同且与语言规范完全匹配的单一 SQL 数据类型。我还没有找到一个。

于 2013-06-27T17:00:26.573 回答