MySQL WHERE 子句中未引用 CTE
MySQL CTE not referenced in WHERE clause
我无法理解为什么 CTE
不能从 WHERE
子句中引用。
在下面的代码中,第一个查询工作正常,但在第二个查询中,只需将 WHERE
子句中的值替换为计算该值的 CTE,就会产生错误“Unknown column 'cte' in 'where clause'".
# This query works
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN ('1332');
# But this query produces an error
WITH
cte AS (SELECT '1332')
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN (cte);
# Here is some data to test these two queries with
CREATE TABLE stock_prices (Country_Exchange_Code VARCHAR(2), Stock_Code VARCHAR(4), Date DATE, Close FLOAT);
INSERT INTO stock_prices VALUES
("T", "1301", '2019-10-29', 75.2),
("T", "1301", '2019-10-30', 76.6),
("T", "1301", '2019-10-31', 77.6),
("T", "1301", '2019-11-01', 77.2),
("T", "1332", '2019-10-29', 52.5),
("T", "1332", '2019-10-30', 49.7),
("T", "1332", '2019-10-31', 50.8),
("T", "1332", '2019-11-01', 50.4),
("T", "1333", '2019-10-29', 13.9),
("T", "1333", '2019-10-30', 13.8),
("T", "1333", '2019-10-31', 14.3),
("T", "1333", '2019-11-01', 14.4);
你可以这样做:
WITH
cte AS (SELECT '1332' as code)
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN (select code from cte);
结果:
Country_Exchange_Code Stock_Code Date Close
---------------------- ----------- ----------- -----
T 1332 2019-10-29 52.5
T 1332 2019-10-30 49.7
T 1332 2019-10-31 50.8
T 1332 2019-11-01 50.4
您的查询有两个问题:
IN
需要形式为 SELECT ...
的正式子查询
- cte 需要命名列;这就是为什么我添加
as code
.
参见 DB Fiddle 中的 运行 示例。
听起来您正在将 cte 视为某种变量,而不是将其视为虚拟 table。
你做不到IN (cte)
就像你做不到IN (sometablename)
一样;它需要 IN (select somecol from sometablename)
.
您可以使用 TABLE
关键字通过名称引用 cte
或另一个 table(不使用它的子选择)。
WITH
cte AS (SELECT '1332')
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN (TABLE cte);
我无法理解为什么 CTE
不能从 WHERE
子句中引用。
在下面的代码中,第一个查询工作正常,但在第二个查询中,只需将 WHERE
子句中的值替换为计算该值的 CTE,就会产生错误“Unknown column 'cte' in 'where clause'".
# This query works
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN ('1332');
# But this query produces an error
WITH
cte AS (SELECT '1332')
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN (cte);
# Here is some data to test these two queries with
CREATE TABLE stock_prices (Country_Exchange_Code VARCHAR(2), Stock_Code VARCHAR(4), Date DATE, Close FLOAT);
INSERT INTO stock_prices VALUES
("T", "1301", '2019-10-29', 75.2),
("T", "1301", '2019-10-30', 76.6),
("T", "1301", '2019-10-31', 77.6),
("T", "1301", '2019-11-01', 77.2),
("T", "1332", '2019-10-29', 52.5),
("T", "1332", '2019-10-30', 49.7),
("T", "1332", '2019-10-31', 50.8),
("T", "1332", '2019-11-01', 50.4),
("T", "1333", '2019-10-29', 13.9),
("T", "1333", '2019-10-30', 13.8),
("T", "1333", '2019-10-31', 14.3),
("T", "1333", '2019-11-01', 14.4);
你可以这样做:
WITH
cte AS (SELECT '1332' as code)
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN (select code from cte);
结果:
Country_Exchange_Code Stock_Code Date Close
---------------------- ----------- ----------- -----
T 1332 2019-10-29 52.5
T 1332 2019-10-30 49.7
T 1332 2019-10-31 50.8
T 1332 2019-11-01 50.4
您的查询有两个问题:
IN
需要形式为SELECT ...
的正式子查询
- cte 需要命名列;这就是为什么我添加
as code
.
参见 DB Fiddle 中的 运行 示例。
听起来您正在将 cte 视为某种变量,而不是将其视为虚拟 table。
你做不到IN (cte)
就像你做不到IN (sometablename)
一样;它需要 IN (select somecol from sometablename)
.
您可以使用 TABLE
关键字通过名称引用 cte
或另一个 table(不使用它的子选择)。
WITH
cte AS (SELECT '1332')
SELECT * FROM stock_prices
WHERE Country_Exchange_Code = 'T' AND Stock_Code IN (TABLE cte);