如何使用 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

由于没有预期的输出,我只尝试了 运行 查询。