我想知道是否有更有效的方法来编写以下查询(注意重复使用相同的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;
谢谢!
答案 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;