如何在没有联合的情况下编写以下查询?或者我可以使用简单的子查询或使用连接编写以下查询吗? 我的要求是我必须使用querydsl获取结果。由于querydsl不支持工会运作。我想用连接编写下面的查询然后使用querydsl调用它。 //以下查询用于获取车队日历详细信息
SELECT * FROM
(SELECT V.ID AS VID,
V.MODEL,
V.VIN,
V.EXTERIOR_COLOR,
V.LICENSE_PLATE,
V.CURRENT_LOCATION,
V.NOTES,
C.ID AS CID,
//PFIS_COMMON_OPS.FORMATNAME concatnating the name
PFIS_COMMON_OPS.FORMATNAME(C.FIRST_NAME,C.LAST_NAME,C.MIDDLE_NAME,2) AS JOURNALIST_NAME ,
C.LICENSE_AFFI_NAME AS AFNAME,
L.DATE_OUT AS DAYOUT,
L.DATE_IN AS DAYIN,
NULL AS HOLD,
'' AS REASONS,
NULL AS ADATE,
L.LOAN_TYPE_ID AS TYPEID
FROM PFIS_VEHICLE_DETAILS V,
PFIS_CONTACT C,
PFIS_VEHICLE_CONTACT_LOAN L
WHERE C.ID =L.CONTACT_ID
AND V.ID =L.VEHICLE_ID
AND L.LOAN_TYPE_ID IN (1,5)
AND ( L.DATE_IN BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY')
OR L.DATE_OUT BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY'))
-- AND LOWER(V.CURRENT_LOCATION) = 'new york'
UNION
--fetch from data for status-Id=5
SELECT V.ID AS VID,
V.MODEL,
V.VIN,
V.EXTERIOR_COLOR,
V.LICENSE_PLATE,
V.CURRENT_LOCATION,
V.NOTES,
0 AS CID,
'' AS JOURNALIST_NAME ,
'' AS AFNAME,
NULL AS DAYOUT,
NULL AS DAYIN ,
S.ON_HOLD_TILL AS HOLD,
S.REASONS_FOR_HOLD AS REASONS,
S.ANTICIPATED_DATE AS ADATE,
-1 AS TYPEID
FROM PFIS_VEHICLE_DETAILS V,
PFIS_VEHICLE_DETAIL_STATUS S
WHERE V.ID =S.VEHICLE_ID
AND S.STATUS_ID=4
AND ( S.ANTICIPATED_DATE BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY')
OR S.ON_HOLD_TILL BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY'))
--AND LOWER(V.CURRENT_LOCATION) = 'new york'
)
提前致谢...
答案 0 :(得分:0)
如果既不支持UNION
也不支持INCLUDE
,则不会有简单的答案。
对FROM和WHERE子句进行以下更改应该可以解决问题。 注意我强烈建议您养成使用JOIN
子句的习惯,而不是在WHERE
子句中混合使用连接条件和过滤器。它有点冗长,但如果使用体面的格式,则更容易阅读和发现错误。
请记住,这是假设,因为您还没有提供样本数据:每个
PFIS_VEHICLE_DETAILS
行在联合的第一部分或第二部分最多出现一次;从来没有。否则,你必须多做一些工作才能让你的行在必要时加倍。
FROM PFIS_VEHICLE_DETAILS V
/* First part of union. LEFT JOIN bc presumably rows aren't expected to match rows from second part of union. */
LEFT JOIN (
/* Use subquery to filter bc values would be NULL in non matching rows. */
SELECT *
FROM PFIS_VEHICLE_CONTACT_LOAN L
WHERE L.LOAN_TYPE_ID IN (1, 5)
AND ( L.DATE_IN BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY')
OR L.DATE_OUT BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY'))
) L ON
V.ID = L.VEHICLE_ID
LEFT JOIN PFIS_CONTACT C ON
C.ID = L.CONTACT_ID
/* Second part of union */
LEFT JOIN (
SELECT *
FROM PFIS_VEHICLE_DETAIL_STATUS S
WHERE S.STATUS_ID=4
AND ( S.ANTICIPATED_DATE BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY')
OR S.ON_HOLD_TILL BETWEEN TO_DATE('04/01/2014','DD/MM/YYYY') AND TO_DATE('05/10/2014','DD/MM/YYYY'))
) S ON
V.ID = S.VEHICLE_ID
如果上述方法无效,则使用UNION
模拟FULL OUTER JOIN
的方法很复杂,可以更普遍地应用。 但它变得混乱 - 你可能想要考虑是否正在使用正确的工具来完成工作;即放弃该工具,转而支持 支持UNION。
方法是使用FULL OUTER JOIN
构建一个结合了2个union-parts(我们将调用U1和U2)的结果集,类似于以下内容:
U1.C1 U1.C2 U2.C1 U2.C2 JOIN_COL 1-1 xx NULL NULL U1 1-2 yy NULL NULL U1 1-3 zz NULL NULL U1 NULL NULL 2-1 aa U2 NULL NULL 2-2 bb U2 NULL NULL 2-3 cc U2
然后您将U1.C1
与U2.C1
合并,同样U1.C2
与U2.C2
合并。
您的查询结构类似于以下内容:
SELECT u1.C1, u1.C2, u2.C1, u2.C2, COALESCE(u1.JOIN_COL, u2.JOIN_COL) as JOIN_COL
FROM ( /* JOIN_COL is important as it allows joining U1 and U2 without matching rows */
SELECT 'U1' as JOIN_COL,
C1, C2, ...
FROM ...
) u1 /* Subquery for part of "union" */
FULL OUTER JOIN (
SELECT 'U2' as JOIN_COL,
C1, C2, ...
FROM ...
) u2 ON /* Subquery for part of "union" */
u1.JOIN_COL = u2.JOIN_COL
给定的SELECT
演示了对象的第一部分。将其替换为以下内容以获得最终的模拟UNION。
SELECT COALESCE(u1.C1, u2.C1) as C1,
COALESCE(u1.C2, u2.C2) as C2,
... /* Note JOIN_COL obviously not needed in final output */