在从一个在线课程学习MySQL时,我偶然发现了这个练习(或多或少,我在这里简化它):

Task 1:使用公用表表达式(CTE)优化以下查询.

SELECT CONCAT("Cl1: ", COUNT(OrderID), "orders") AS "Total" 
FROM Orders WHERE YEAR(Date) = 2022 AND ClientID = "Cl1" 
UNION 
SELECT CONCAT("Cl2: ", COUNT(OrderID), "orders") 
FROM Orders WHERE YEAR(Date) = 2022 AND ClientID = "Cl2";

这是他们的解决方案(我理解):

WITH 
CL1_Orders AS (SELECT CONCAT("Cl1: ", COUNT(OrderID), "orders") AS "Total number of orders"  
FROM Orders WHERE YEAR(Date) = 2022 AND ClientID = "Cl1"), 
CL2_Orders AS (SELECT  CONCAT("Cl2: ", COUNT(OrderID), "orders") 
FROM Orders WHERE YEAR(Date) = 2022 AND ClientID = "Cl2")
SELECT * FROM CL1_Orders UNION SELECT * FROM CL2_Orders;

正如在课程的前一节中我使用存储过程一样,我想修改解决方案并使用它们.我写了下面的代码:

DELIMITER //
CREATE PROCEDURE totalOrders (IN client VARCHAR(10))
BEGIN
    SELECT CONCAT(client, ": ", COUNT(OrderID), "orders") 
    FROM Orders 
    WHERE YEAR(Date) = 2022 AND ClientID = client;
END//

DELIMITER ;
WITH 
SELECT * FROM CALL totalOrders("Cl1") AS cl1,
SELECT * FROM CALL totalOrders("Cl2") AS cl2
SELECT * FROM cl1 UNION SELECT * FROM cl2;

执行它会导致语法错误ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM CALL totalOrders("Cl1") AS cl1, SELECT * FROM CALL totalOrders("Cl' at line 2

我怎么才能修好它呢?怎么啦?

推荐答案

MySQL没有返回类型表,因此您需要改变您的方法

就像一张临时桌子

此外,这一点和您的查询将利用(Year(Date),ClientID)上的索引获利

告诉你:永远不要用列名命名变量,每个数据库都有POINT来确定你的意思,更简单的是有一个p_before,这可以帮助你更好地reqad代码,数据库有机会给你正确的答案

CREATE tABLE Orders (OrderID int, client varchar(10),ClientID int,  Date date) 
INSERT INTO Orders VALUES ( 1,'test1',1,NOW() - INTERVAL 2 YEAR);
INSERT INTO Orders VALUES ( 2,'test2',2,NOW() - INTERVAL 2 YEAR)
CREATE Temporary table t_temop (Orderclinet varchar(100)) 
CREATE PROCEDURE totalOrders (IN p_client VARCHAR(10))
BEGIN
     INSERT INTO t_temop
    SELECT CONCAT(MAX(client), ": ", COUNT(OrderID), " order(s)") 
    FROM Orders 
    WHERE YEAR(Date) = 2022 AND ClientID = p_client;
END
CALL totalOrders(1);
  CALL totalOrders(2);
SELECT * FROM t_temop
Orderclinet
test1: 1 order(s)
test2: 1 order(s)

fiddle

Mysql相关问答推荐

从insert语句获取新生成的虚拟UUID

实体内约束的唯一增量 ID 生成

过滤值为0时如何在MySQL查询中设置条件?

是否可以使用以EXPLAIN EXTENDED ...开头的 SQL 语句修改数据?

SQL:如何为给定组中的所有记录 Select 一列与另一列不匹配的位置

为什么以及如何将 Django filter-by BooleanField 查询转换为 SQL WHERE 或 WHERE NOT 而不是 1/0?

如何在 SQL 中计算留存曲线?

MYSQL 删除两个已知字符串之间的字符串

如何使用 express.js 和 react.js 删除连接表中的元素和关联元素

MySQL 根据另一列中的值更改空值

Django中的MYSQL查询等效

INNER JOIN 问题(MySQL 错误代码:1054)

限制正则​​表达式中多字符通配符的范围

具有别名主机的 ssh 反向 mysql tunel

MySQL - 计算行重复的最大计数

用序列号mysql更新列

如何在 MySQL 中 Select 字段具有最小值的数据?

在 spring-boot jpa hibernate 中 >4<24 后与 Db 的连接终止

我可以在单个 Amazon RDS 实例上创建多少个数据库

MySQL - 重复表