将 2 个查询合并为 1 个(select 基于其他 select)
Combining 2 queries in 1 (select based on other select)
我有 2 个问题:
SELECT EW_OBIEKTY.STATUS
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE (((EW_OBIEKTY.STATUS)=0) AND ((EW_OB_ELEMENTY.TYP)<>1));
第二个基于第一个
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, [**result of 1st one**].IDE, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE LEFT JOIN [**result of 1st one**] ON EW_POLYLINE.ID = [**result of 1st one**].IDE
WHERE (((EW_POLYLINE.STAN_ZMIANY)=0) AND (([**result of 1st one**].IDE) Is Null));
它们工作得很好,但我需要它们作为一个组合查询工作,访问结果如下所示:
SELECT EW_POLYLINE.ID
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
, EW_OB_ELEMENTY.TYP
, EW_OBIEKTY.STATUS
, EW_POLYLINE.STAN_ZMIANY
FROM (EW_POLYLINE
LEFT JOIN EW_OB_ELEMENTY
ON EW_POLYLINE.ID = EW_OB_ELEMENTY.IDE)
INNER JOIN EW_OBIEKTY
ON EW_OB_ELEMENTY.UIDO = EW_OBIEKTY.UID
WHERE (((EW_OB_ELEMENTY.IDE) Is Null)
AND ((EW_OB_ELEMENTY.TYP)<>1)
AND ((EW_OBIEKTY.STATUS)<>3)
AND ((EW_POLYLINE.STAN_ZMIANY)=0));
但这只给我一个空table。你能帮帮我吗?
您的 inner join
取决于 left join
的右侧 table,这有效地将 left join
转换为 inner join
。这意味着条件 ((EW_OB_ELEMENTY.IDE) Is Null)
将 始终 为假,并且您的整个 where
条件评估为假,因此结果集为空。
您需要将第一个查询嵌套在第二个查询中:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, a.IDE, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
LEFT JOIN (
SELECT EW_OBIEKTY.STATUS
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
) as a ON EW_POLYLINE.ID = a.IDE
WHERE EW_POLYLINE.STAN_ZMIANY = 0 AND a.IDE Is Null
或者,使用 common table expression:
with a as (
SELECT EW_OBIEKTY.STATUS
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
)
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
LEFT JOIN a ON EW_POLYLINE.ID = a.IDE
WHERE EW_POLYLINE.STAN_ZMIANY = 0 AND a.IDE Is Null
或者,您可以重新排序联接(并将 left join
替换为 right join
)并将某些条件从 where 移至联接子句:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, EW_POLYLINE.ID_WARSTWY
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO AND EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
RIGHT JOIN EW_POLYLINE
ON EW_POLYLINE.ID = EW_OB_ELEMENTY.IDE
WHERE EW_POLYLINE.STAN_ZMIANY = 0 AND EW_OB_ELEMENTY.IDE Is Null
您还可以通过将括号从第一个连接移到第二个并将某些条件从连接条件中移动来更改连接的评估顺序:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
LEFT JOIN (EW_OB_ELEMENTY
INNER JOIN EW_OBIEKTY
ON EW_OB_ELEMENTY.UIDO = EW_OBIEKTY.UID
AND EW_OB_ELEMENTY.TYP <> 1
AND EW_OBIEKTY.STATUS <> 3)
ON EW_POLYLINE.ID = EW_OB_ELEMENTY.IDE
WHERE EW_OB_ELEMENTY.IDE Is Null
AND EW_POLYLINE.STAN_ZMIANY = 0
另一种可能性是使用 not exists
-predicate:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, a.IDE, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
WHERE EW_POLYLINE.STAN_ZMIANY = 0
AND NOT EXISTS (
SELECT 1
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
AND EW_OB_ELEMENTY.IDE = EW_POLYLINE.ID
)
最后一个可能是最好的,因为在我看来,它比其他的更容易理解,因为它更清楚地显示了您正在查询的内容(EW_POLYLINE
中没有的行满足特定条件的行(not exists
)。
我有 2 个问题:
SELECT EW_OBIEKTY.STATUS
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE (((EW_OBIEKTY.STATUS)=0) AND ((EW_OB_ELEMENTY.TYP)<>1));
第二个基于第一个
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, [**result of 1st one**].IDE, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE LEFT JOIN [**result of 1st one**] ON EW_POLYLINE.ID = [**result of 1st one**].IDE
WHERE (((EW_POLYLINE.STAN_ZMIANY)=0) AND (([**result of 1st one**].IDE) Is Null));
它们工作得很好,但我需要它们作为一个组合查询工作,访问结果如下所示:
SELECT EW_POLYLINE.ID
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
, EW_OB_ELEMENTY.TYP
, EW_OBIEKTY.STATUS
, EW_POLYLINE.STAN_ZMIANY
FROM (EW_POLYLINE
LEFT JOIN EW_OB_ELEMENTY
ON EW_POLYLINE.ID = EW_OB_ELEMENTY.IDE)
INNER JOIN EW_OBIEKTY
ON EW_OB_ELEMENTY.UIDO = EW_OBIEKTY.UID
WHERE (((EW_OB_ELEMENTY.IDE) Is Null)
AND ((EW_OB_ELEMENTY.TYP)<>1)
AND ((EW_OBIEKTY.STATUS)<>3)
AND ((EW_POLYLINE.STAN_ZMIANY)=0));
但这只给我一个空table。你能帮帮我吗?
您的 inner join
取决于 left join
的右侧 table,这有效地将 left join
转换为 inner join
。这意味着条件 ((EW_OB_ELEMENTY.IDE) Is Null)
将 始终 为假,并且您的整个 where
条件评估为假,因此结果集为空。
您需要将第一个查询嵌套在第二个查询中:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, a.IDE, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
LEFT JOIN (
SELECT EW_OBIEKTY.STATUS
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
) as a ON EW_POLYLINE.ID = a.IDE
WHERE EW_POLYLINE.STAN_ZMIANY = 0 AND a.IDE Is Null
或者,使用 common table expression:
with a as (
SELECT EW_OBIEKTY.STATUS
, EW_OB_ELEMENTY.IDE
, EW_OB_ELEMENTY.TYP
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
)
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
LEFT JOIN a ON EW_POLYLINE.ID = a.IDE
WHERE EW_POLYLINE.STAN_ZMIANY = 0 AND a.IDE Is Null
或者,您可以重新排序联接(并将 left join
替换为 right join
)并将某些条件从 where 移至联接子句:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, EW_POLYLINE.ID_WARSTWY
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO AND EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
RIGHT JOIN EW_POLYLINE
ON EW_POLYLINE.ID = EW_OB_ELEMENTY.IDE
WHERE EW_POLYLINE.STAN_ZMIANY = 0 AND EW_OB_ELEMENTY.IDE Is Null
您还可以通过将括号从第一个连接移到第二个并将某些条件从连接条件中移动来更改连接的评估顺序:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
LEFT JOIN (EW_OB_ELEMENTY
INNER JOIN EW_OBIEKTY
ON EW_OB_ELEMENTY.UIDO = EW_OBIEKTY.UID
AND EW_OB_ELEMENTY.TYP <> 1
AND EW_OBIEKTY.STATUS <> 3)
ON EW_POLYLINE.ID = EW_OB_ELEMENTY.IDE
WHERE EW_OB_ELEMENTY.IDE Is Null
AND EW_POLYLINE.STAN_ZMIANY = 0
另一种可能性是使用 not exists
-predicate:
SELECT EW_POLYLINE.P0_X, EW_POLYLINE.P0_Y, EW_POLYLINE.ID, EW_POLYLINE.STAN_ZMIANY, a.IDE, EW_POLYLINE.ID_WARSTWY
FROM EW_POLYLINE
WHERE EW_POLYLINE.STAN_ZMIANY = 0
AND NOT EXISTS (
SELECT 1
FROM EW_OBIEKTY
INNER JOIN EW_OB_ELEMENTY
ON EW_OBIEKTY.UID = EW_OB_ELEMENTY.UIDO
WHERE EW_OBIEKTY.STATUS = 0 AND EW_OB_ELEMENTY.TYP <> 1
AND EW_OB_ELEMENTY.IDE = EW_POLYLINE.ID
)
最后一个可能是最好的,因为在我看来,它比其他的更容易理解,因为它更清楚地显示了您正在查询的内容(EW_POLYLINE
中没有的行满足特定条件的行(not exists
)。