MySQL - 重用嵌套的select语句

时间:2015-06-19 11:07:08

标签: mysql stored-procedures common-table-expression

我想知道是否有更有效的方法来编写以下查询(注意重复使用相同的select语句导致A)。我不会过分担心它,但我需要在此添加一两个“父级”级别,看起来似乎必须有比我天真的方法更好的方法。

SELECT A.*, I.INVOICE_STATUS
FROM ( SELECT E.*, IL.INVOICE_LINE_ID, IL.INVOICE_LINE_INVOICE_ID
       FROM EXPENSE E
       LEFT JOIN INVOICE_LINE IL
       ON E.EXPENSE_ID = IL.INVOICE_LINE_EXPENSE_ID
       UNION
       SELECT E.*, IL.INVOICE_LINE_ID, IL.INVOICE_LINE_INVOICE_ID
       FROM EXPENSE E
       RIGHT JOIN INVOICE_LINE IL
       ON E.EXPENSE_ID = IL.INVOICE_LINE_EXPENSE_ID) A
LEFT JOIN INVOICE I
ON A.INVOICE_LINE_INVOICE_ID = I.INVOICE_ID
UNION
SELECT A.*, I.INVOICE_STATUS, I.INVOICE_DUE_DATE
FROM ( SELECT E.*, IL.INVOICE_LINE_ID, IL.INVOICE_LINE_INVOICE_ID
       FROM EXPENSE E
       LEFT JOIN INVOICE_LINE IL
       ON E.EXPENSE_ID = IL.INVOICE_LINE_EXPENSE_ID
       UNION
       SELECT E.*, IL.INVOICE_LINE_ID, IL.INVOICE_LINE_INVOICE_ID
       FROM EXPENSE E
       RIGHT JOIN INVOICE_LINE IL
       ON E.EXPENSE_ID = IL.INVOICE_LINE_EXPENSE_ID) A
RIGHT JOIN INVOICE I
ON A.INVOICE_LINE_INVOICE_ID = I.INVOICE_ID;

谢谢!

1 个答案:

答案 0 :(得分:0)

在Oracle中,您可以使用WITH关键字创建所谓的公用表表达式。它的工作原理如下:

WITH ORACLE_CTE AS (SELECT * FROM DUAL CONNECT BY LEVEL <= 10);

在MySQL中,你没有像在Oracle中那样拥有奢侈品。所以,你会这样做:

创建一个过程来创建一个临时表,该表存储以下结果集:

SELECT E.*, IL.INVOICE_LINE_ID, IL.INVOICE_LINE_INVOICE_ID
FROM EXPENSE E
LEFT JOIN INVOICE_LINE IL
ON E.EXPENSE_ID = IL.INVOICE_LINE_EXPENSE_ID
UNION
SELECT E.*, IL.INVOICE_LINE_ID, IL.INVOICE_LINE_INVOICE_ID
FROM EXPENSE E
RIGHT JOIN INVOICE_LINE IL
ON E.EXPENSE_ID = IL.INVOICE_LINE_EXPENSE_ID;

然后,在您应用UNION的两个查询中重用临时表。

SELECT A.*, I.INVOICE_STATUS
FROM CTE_MYSQL_TABLE
LEFT JOIN INVOICE I
ON A.INVOICE_LINE_INVOICE_ID = I.INVOICE_ID
UNION
SELECT A.*, I.INVOICE_STATUS, I.INVOICE_DUE_DATE
FROM CTE_MYSQL_TABLE
RIGHT JOIN INVOICE I
ON A.INVOICE_LINE_INVOICE_ID = I.INVOICE_ID;