mysql - 如何使用 CTE 和左连接编写查询
问题描述
我正在尝试使用我的 CTE 建立一个日历表并进行设置,以便我的查询中的日期像这样显示
1 月 18 日
1 月 19
日 2 月 18日 2
月 19 日
现在这是我的 DDL,这是我尝试的查询,但是在 MySql Workbench 中,我收到错误消息,即我的 sql 某处存在错误。
这是确切的错误:
查询错误:错误:ER_PARSE_ERROR:您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的 'RECURSIVE cte_months_to_pull AS ( SELECT DATE_FORMAT(@start_date, '%Y-%m-01'' ) 附近使用正确的语法
有人可以帮忙吗?
如果它更容易,这是一个 SQL Fiddle http://sqlfiddle.com/#!9/300f9d/1
CREATE TABLE PrevYear (
`EmployeeNumber` char(8) NOT NULL,
`SaleAmount` int DEFAULT NULL,
`SaleDate` date NOT NULL,
`EmployeeName` char(17) NOT NULL
);
CREATE TABLE CurrentYear (
`EmployeeNumber` char(8) NOT NULL,
`SaleAmount` int DEFAULT NULL,
`SaleDate` date NOT NULL,
`EmployeeName` char(17) NOT NULL
);
INSERT INTO CurrentYear
VALUES ('ea12', '100', '2019-01-10', 'Maggie Samuels');
INSERT INTO CurrentYear
VALUES ('ea12', '199', '2019-01-13', 'Sam Stoner');
INSERT INTO CurrentYear
VALUES ('ea12', '100', '2019-03-01', 'Jake Jolel');
INSERT INTO CurrentYear
VALUES ('ls22', '100', '2019-05-01', 'Maggie Samuels');
INSERT INTO PrevYear
VALUES ('ea12', '100', '2018-01-10', 'Maggie Samuels');
INSERT INTO PrevYear
VALUES ('ea12', '199', '2018-01-13', 'Sam Stoner');
INSERT INTO PrevYear
VALUES ('ea12', '100', '2018-03-01', 'Sam Stoner');
INSERT INTO PrevYear
VALUES ('ls22', '100', '2018-05-01', 'Maggie Samuels');
这是我尝试的查询:
SET @start_date = '20190102';
SET @number_of_months = 12;
WITH RECURSIVE
cte_months_to_pull AS (
SELECT DATE_FORMAT(@start_date, '%Y-%m-01')
- INTERVAL @number_of_months MONTH AS month_to_pull
UNION ALL
SELECT month_to_pull + INTERVAL 1 MONTH
FROM cte_months_to_pull
WHERE month_to_pull < @start_date + INTERVAL @number_of_months - 2 MONTH
)
SELECT Date_format(saledate, '%m-%Y') AS Month,
employeename,
Sum(saleamount) AS IA
FROM currentyear
WHERE employeename = 'Maggie Samuels'
GROUP BY Date_format(saledate, '%m-%Y'), employeename
UNION ALL
SELECT Date_format(saledate, '%m-%Y') AS Month,
employeename,
Sum(saleamount) AS IA
FROM prevyear
WHERE employeename = 'Maggie Samuels'
GROUP BY Date_format(saledate, '%m-%Y'), employeename
LEFT JOIN cte_months_to_pull (
Select DATE_Format(month_to_pull, '%b %y')
FROM cte_months_to_pull
) AS YRS ON month_to_pull = saledate
ORDER BY MONTH(month_to_pull), YEAR(month_to_pull)
解决方案
如我所见,您使用的 MySQL 版本早于 8.0,它不支持 RECURSIVE CTE。我已经用 8.0 的一些小更新尝试了您的查询,它运行良好 -
WITH RECURSIVE
cte_months_to_pull AS (
SELECT DATE_FORMAT(@start_date, '%Y-%m-01')
- INTERVAL @number_of_months MONTH AS month_to_pull
UNION ALL
SELECT month_to_pull + INTERVAL 1 MONTH
FROM cte_months_to_pull
WHERE month_to_pull < @start_date + INTERVAL @number_of_months - 2 MONTH
)
SELECT YRS.months_to_pull
,T.employeename
,COALESCE(T.IA, 0) IA
FROM (SELECT DATE_Format(month_to_pull, '%b-%Y') months_to_pull
FROM cte_months_to_pull
ORDER BY months_to_pull
) AS YRS
LEFT JOIN (SELECT Date_format(saledate, '%b-%Y') AS `Month`
,employeename
,Sum(saleamount) AS IA
FROM CurrentYear
WHERE employeename = 'Maggie Samuels'
GROUP BY Date_format(saledate, '%b-%Y'), employeename
UNION ALL
SELECT Date_format(saledate, '%b-%Y')
,employeename
,Sum(saleamount)
FROM PrevYear
WHERE employeename = 'Maggie Samuels'
GROUP BY Date_format(saledate, '%b-%Y'), employeename) T
ON YRS.months_to_pull = T.`Month`
ORDER BY month(STR_TO_DATE(CONCAT('01-',months_to_pull), '%d-%b-%Y'))
,YEAR(STR_TO_DATE(CONCAT('01-',months_to_pull), '%d-%b-%Y'))
这是小提琴
由于没有预期的输出,我只尝试运行查询。
推荐阅读
- docker - Docker 通过运行命令加载但无法访问控制台
- python-3.x - APscheduler 和 Pyramid python
- java - 如何使用 Selenium 和 Java 在 https://www.phptravels.net/ 网站中提取 HTML5 约束验证的文本?
- javascript - 尝试在模态中加载包含 2 个不同对象列表的模型
- mysql - 如何获得最近 30 天内超过 1000 美元的用户?每个用户过去 30 天。SQL 有限制
- java - CardPanel:获取空指针异常 - IntelliJ
- kendo-ui - Kendo 中未涵盖 Angular 网格的模板背景
- javascript - 使用滑块内的按钮的materializecss轮播下一个方法(javascript)
- php - 我的下拉列表选项正在更改为 php 中提交按钮上的先前位置
- node.js - API 控制器:无法 PUT,无法删除(未找到 404)