如何使用 CTE 和左连接编写查询
How To Write A Query With A CTE And A Left Join
我正在尝试使用我的 CTE 设置一个日历 table 并进行设置,以便我的查询中的日期显示如下
Jan 18
Jan 19
Feb 18
Feb 19
现在这是我的 DDL,这是我尝试的查询,但是在 MySql Workbench 中,我得到的错误是我的 sql 某处有错误。
这是准确的错误:
Query Error: Error: ER_PARSE_ERROR: 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 'RECURSIVE cte_months_to_pull AS ( SELECT DATE_FORMAT(@start_date, '%Y-%m-01'' at line 1
有人可以帮忙吗?
如果更简单的话,这是 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,不支持递归 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'))
这是Fiddle
由于没有预期的输出,我只尝试了 运行 查询。
我正在尝试使用我的 CTE 设置一个日历 table 并进行设置,以便我的查询中的日期显示如下
Jan 18
Jan 19
Feb 18
Feb 19
现在这是我的 DDL,这是我尝试的查询,但是在 MySql Workbench 中,我得到的错误是我的 sql 某处有错误。
这是准确的错误:
Query Error: Error: ER_PARSE_ERROR: 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 'RECURSIVE cte_months_to_pull AS ( SELECT DATE_FORMAT(@start_date, '%Y-%m-01'' at line 1
有人可以帮忙吗?
如果更简单的话,这是 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,不支持递归 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'))
这是Fiddle
由于没有预期的输出,我只尝试了 运行 查询。