MySQL相当于Oracle中的WITH


Answers:


16

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

ANSI / ISO SQL WITH关键字用于定义公用表表达式(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 ;

在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 ;

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


为了避免重复(代码重复),使用变量和临时表不是更好吗?
Pacerier,2015年

我不会担心代码重复,但是出于性能原因,我当然会考虑并尝试使用带有临时表的版本。
ypercubeᵀᴹ

1
为什么说您不担心重复代码?这是完全凌乱和未  干燥的
Pacerier,2015年

1
@Pacerier DRY并不总是与数据库代码相关。
JNK 2015年

1
@Pacerier如果没有,我不会感到惊讶。数据库引擎需要做出有根据的猜测,以找出最有效的方法,同时还要保证返回正确的结果。临时表通常很好,但是DRY在其他方面(如用户定义的函数)会导致DB的性能糟糕。
JNK 2015年

2

那会行得通,但是很遗憾,它没有提供使用WITH子句的优势,即不会多次执行相同的查询(复杂的查询可能真的很慢,并且对数据库引擎的要求很高;我遭受了它) 。

我建议将原始WITH子句中定义的每个SELECT插入其自己的临时表中,并在query中使用它们。在MySQL中,一旦用户会话结束,临时表将自行删除。

编辑:

我只是在类似的线程中看到了这个答案,该线程清楚地揭示了MySQL的3种解决方法

  • 临时表
  • 派生表
  • 内联视图(有效地代表WITH子句-它们是可互换的)

/programming//a/1382618/2906290

还有一个MySQL过程的示例,该过程创建并删除临时表,以防您继续进行会话并希望释放这些资源(我将其用作语法示例):https : //stackoverflow.com/a/ 5553145/2906290

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.