mysql:不能/如何将子查询用作完全限定的cte

z0qdvdin  于 2021-06-24  发布在  Mysql
关注(0)|答案(1)|浏览(317)

我想执行以下操作。这在mysql中是非法的。postgresql中关联的cte(“with”子句)不起作用。这里的假设是mysql中的子查询不是完全限定的cte。
请注意:这个查询显然是非常愚蠢的,它刚刚被净化和缩短,为您的观赏乐趣和简洁地突出问题。
另外请注意,“获取对称差分”任务与手头的问题是正交的。

SELECT A.val
FROM
  (SELECT val FROM tableA) AS A,
  (SELECT val FROM tableB) AS B
WHERE (A.val NOT IN (SELECT val FROM B)
       OR B.val NOT IN (SELECT val FROM A));

postgres的例子(坦白地说,没有测试过,因为我目前没有postgres数据库可供测试,但我100%肯定它会起作用……我过去也做过类似的事情):

WITH A as (SELECT val FROM tableA),
     B as (SELECT val from tableB)
SELECT A.val FROM A, B
WHERE (A.val NOT IN (SELECT val FROM B)
       OR B.val NOT IN (SELECT val FROM A));
avkwfej4

avkwfej41#

更新
mysql 8.0引入了对公共表表达式(cte)的支持,即早期版本mysql不支持的“with”。
https://dev.mysql.com/doc/refman/8.0/en/with.html
编辑
是的,我们可以将一个别名分配给一个内联视图(或者,mysql文言文中的派生表),并在查询的其他地方引用该别名。在这个例子中, my_query 是我们指定给内联视图的别名。

SELECT my_query.val 
   FROM ( SELECT val FROM foo )  my_query
  WHERE my_query.val 
  ORDER
     BY my_query.val

但我们不能在子查询的from子句中引用该别名。例如,在此构造中:

SELECT my_query.val 
   FROM ( SELECT val FROM foo )  my_query
  WHERE 7 IN ( SELECT val FROM my_query )
  ORDER
     BY my_query.val

语法实际上是有效的。但是提到 my_queryFROM 合同条款 IN (subquery) 不是也不能是对外部查询中表别名的引用。这是不允许的。
所以我们希望查询可能会抛出一个错误 my_query 子查询中的引用是未解析的标识符“unknown table”,类似于此。
注意,我们可以创建一个名为 my_query ,例如。

CREATE TABLE my_query (val INT PRIMARY KEY);
INSERT INTO my_query (val) VALUES (7);

然后重新运行查询,然后 my_query 现在,我决定坐到table上(不是查询中指定的别名。)
公共表表达式(commontableexpression,cte)在解决这类问题方面向前迈出了重要一步,它能够在其他情况下不允许的多个位置引用内联视图。
如果问题是“如何在mysql中模拟common table expression(cte)功能”,谷歌搜索会引出这个问题:
在mysql中如何使用“with”子句?
起初的
你是指cte(公共表表达式,即with子句)而不是cmt吗?
如果你是指cmt,我很抱歉,因为在这个问题的上下文中,不清楚这个缩写词代表什么。也许这意味着集中管理的表,但我不明白这有什么关系。
如果你问mysql是否支持公共表表达式(commontableexpression,cte),答案是否定的,或者至少现在还不支持。
从发布的sql示例来看,似乎不需要cte或内联视图,甚至子查询。也许sql已经被过度简化到不清楚查询应该实现什么的程度(它不应该得到一个对称的差异,所以我们不打算提出明显的替代方案,如何在mysql中做到这一点。
将子查询(select)与 IN 以及 NOT IN . 它们都是有效的:

foo IN ( subquery )

    foo NOT IN ( subquery )

一个大“抓到”了 NOT IN (subquery) 是子查询返回空值的时间。如果列表中的值为空,则 NOT IN 计算结果为null,这意味着它不能对任何行计算为true。作为示范,请考虑:

SELECT 3 NOT IN (2,NULL,4)

也许这就回答了人们提出的问题。
我们只是在猜测被问到什么问题(有问题吗?)
“不起作用”是什么意思?查询返回意外结果?mysql返回错误?查询执行了很长时间,似乎“挂起”?我们只是在猜测什么不起作用。
为什么我们要使用老式的逗号运算符语法来进行连接操作,而不是(我们还能称它吗?更新) JOIN 关键字?

相关问题