MySQL 相当于 oracle 中的 WITH

Nee*_*rma 13 mysql oracle mysql-5.5

是否有与 Oracle 中的 WITH 子句等效的 MySQL?

ype*_*eᵀᴹ 17

那没有。除非(直到)有人开发它(MySQL 是开源的,任何人都可以做出贡献。)

ANSI/ISO SQLWITH关键字用于定义公用表表达式 (CTE),它通过一个或多个嵌套引用简化了复杂的查询。它在 Oracle、Postgres、SQL-Server、DB2 中可用,但在 MySQL 中不可用。

最终查询可能会引用(通常在FROM子句中,但它们可以在任何其他部分)对任何公共表表达式的引用,一次或多次。可以使用派生表在 MySQL 中编写查询(没有 CTE),但必须重复进行引用。

一个愚蠢的查询示例,显示所有 50 多岁和 7 月份出生的人以及所有同年出生的人的人数:

WITH a AS
    ( SELECT name, birthdate, YEAR(birthdate) AS birthyear
      FROM persons
      WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01' 
    ) 
, b AS
    ( SELECT birthyear, COUNT(*) AS cnt
      FROM a
      GROUP BY birthyear 
    ) 
SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM a JOIN b
  ON a.birthyear = b.birthyear 
WHERE MONTH(a.birthdate) = 7 ;
Run Code Online (Sandbox Code Playgroud)

在 MySQL 中,它可以写成:

SELECT a.name, a.birthdate, b.cnt AS number_of_births
FROM 
    ( SELECT name, birthdate, YEAR(birthdate) AS birthyear
      FROM persons
      WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01' 
    ) AS a 
  JOIN 
    ( SELECT birthyear, COUNT(*) AS cnt
      FROM 
        ( SELECT name, birthdate, YEAR(birthdate) AS birthyear
          FROM persons
          WHERE birthdate >= '1950-01-01' AND birthdate < '1960-01-01' 
        ) AS aa
      GROUP BY birthyear
    ) AS b
  ON a.birthyear = b.birthyear 
WHERE MONTH(a.birthdate) = 7 ;
Run Code Online (Sandbox Code Playgroud)

请注意派生表的代码重复a。在更复杂的查询中,必须多次编写代码。

  • @Pacerier 如果不是,我不会感到惊讶。数据库引擎需要对什么最有效,同时仍保证返回正确结果进行有根据的猜测。临时表一般都很好,但 DRY 在其他方面导致 DB 的性能很差,比如用户定义的函数。 (2认同)