撤消CTE(公用表表达式)

时间:2018-06-19 22:26:06

标签: mysql mariadb common-table-expression

另一位开发人员针对该数据库针对MariaDB(MySQL 10.x版)编写了一个查询,而不应该为MySQL数据库(MySQL 5.6版)编写MySQL数据库。它们不再可用于MySQL 5.6重写。

有人可以协助进行逆向工程吗?

WITH temptable (column1, column2, column3) 
     AS (SELECT t3.column1, 
                t3.column2, 
                CASE 
                  WHEN t3.column3 = 1 
                       AND t2.column3 = 1 THEN 2 
                  ELSE COALESCE(t2.column3, 0) 
                END AS column3 
         FROM   table1 t1 
                JOIN table2 t2 
                  ON t1.column5 = t2.column5 
                     AND t1.column6 = t2.column6 
                JOIN table3 t3 
                  ON t3.column1 = t2.column1 
         WHERE  t1.column4 = :var1 
                AND t1.column6 = :var2 
                AND t3.column7 = 0)
SELECT column2, 
       column3 
FROM   temptable 
UNION 
SELECT t3.column2, 
       t3.column3 
FROM   table3 t3 
WHERE  t3.column7 = -1 
UNION 
SELECT t3.column2, 
       0 AS column3 
FROM   table3 t3 
       LEFT JOIN temptable temp 
              ON temp.column2 = t3.column2 
WHERE  temp.action IS NULL 
       AND t3.column7 = 0;

表和列已更改,以保护无辜者。

1 个答案:

答案 0 :(得分:2)

“便捷按钮”修复程序将采用CTE的定义并将其用作内联视图,以代替外部查询中对temptable的引用。 (这不一定是最佳解决方案,也不是编写查询的最佳方法。)


删去查询的开始部分

WITH temptable 
( column1
, column2
, column3
) 
AS
( SELECT t3.column1
       , t3.column2
       , CASE
           WHEN t3.column3 = 1 AND t2.column3 = 1 THEN 2
           ELSE COALESCE(t2.column3, 0)
         END AS column3 
    FROM table1 t1
    JOIN table2 t2
      ON t1.column5   = t2.column5
     AND t1.column6   = t2.column6
    JOIN table3 t3
      ON t3.column1   = t2.column1
   WHERE t1.column4   = :var1
     AND t1.column6   = :var2 
     AND t3.column7   = 0
)

就这样:

SELECT a.column2
     , a.column3 
  FROM temptable a

 UNION 

SELECT b.column2
     , b.column3 
  FROM table3 b
 WHERE b.column7 = -1

 UNION 

SELECT p.column2
     , 0 AS column3
  FROM table3 p
  LEFT
  JOIN temptable q
    ON q.column2 = p.column2
 WHERE q.action IS NULL
   AND p.column7 = 0

(如对该问题的评论中所述,对action的引用是无效的,因为在action中没有名为temptable的列。)

然后用内联视图定义替换对CTE temptable的引用。

在查询中,别名为aq

赞:

SELECT a.column2
     , a.column3 
  FROM -- temptable
       ( 
         SELECT t3.column1
              , t3.column2
              , CASE
                  WHEN t3.column3 = 1 AND t2.column3 = 1 THEN 2
                  ELSE COALESCE(t2.column3, 0)
                END AS column3 
           FROM table1 t1
           JOIN table2 t2
             ON t1.column5   = t2.column5
            AND t1.column6   = t2.column6
           JOIN table3 t3
             ON t3.column1   = t2.column1
          WHERE t1.column4   = :var1
            AND t1.column6   = :var2 
            AND t3.column7   = 0
       ) a

 UNION

SELECT b.column2
     , b.column3 
  FROM table3 b
 WHERE b.column7 = -1

 UNION 

SELECT p.column2
     , 0 AS column3
  FROM table3 p
  LEFT
  JOIN -- temptable 
       (
         SELECT t3.column1
              , t3.column2
              , CASE
                  WHEN t3.column3 = 1 AND t2.column3 = 1 THEN 2
                  ELSE COALESCE(t2.column3, 0)
                END AS column3 
           FROM table1 t1
           JOIN table2 t2
             ON t1.column5   = t2.column5
            AND t1.column6   = t2.column6
           JOIN table3 t3
             ON t3.column1   = t2.column1
          WHERE t1.column4   = :var1
            AND t1.column6   = :var2 
            AND t3.column7   = 0
       ) q
    ON q.column2 = p.column2
 WHERE q.action IS NULL
   AND p.column7 = 0

编辑

哦,也...在第二次出现的内联视图定义中对:var1:var2占位符的引用可能需要更改为唯一... :var1b:var2b(至少,使用PDO的命名占位符就是这种情况,它们必须是唯一的)

需要为新的绑定占位符提供为:var1:var2提供的值的副本。

关注

问:这个查询...很受欢迎。您提到“轻松解决”,但要花多少钱?

A:在“便捷按钮”修复程序中,两个内联视图aq(代替对CTE的引用)正在分别实现。内联视图查询执行两次,并将结果具体化为两个单独的派生表。 (EXPLAIN输出将显示两个单独的派生表aq。)