首页 > 解决方案 > 将 2 个查询合二为一(根据其他选择进行选择)

问题描述

我有 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));

但这只给了我空桌子。你能帮助我吗?

标签: sqlfirebird

解决方案


inner join取决于 的右侧表格left join,这有效地将其转换left joininner 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

或者,使用公用表表达式

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用 a替换right join)并将一些条件从 where 移动到 join 子句:

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

您还可以通过将括号从第一个连接移动到第二个连接并从 where to join 条件移动一些条件来更改连接的评估顺序:

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-谓词:

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满足特定条件的行 ( ))。


推荐阅读