MySQL - 重用嵌套的 select 语句

MySQL - reuse nested select statement

我想知道是否有更有效的方式来编写以下查询(请注意重复使用相同的 select 语句导致 A)。我不会太担心它,但我需要为此添加一两个 'parent' 级别,而且似乎必须有比我天真的方法更好的方法。

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;

谢谢!

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

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

在 MySQL,您没有在 Oracle 中那么奢侈。所以,你会做如下:

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

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 的两个查询中重复使用临时 table。

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;