条件外适用基于不同外部适用的结果

时间:2015-04-08 08:24:24

标签: sql-server tsql

我有一个需要从多个表中检索数据的查询。对于其中两个表,数据由outer apply检索,因为有必要查询数据的时间范围。

SELECT a.DATA, b1.DATA, c1.DATA
FROM TABLE_A a 
OUTER APPLY 
    (SELECT TOP 1 b.[DATA]
     FROM TABLE_B b
     WHERE b.TIME_START <= a.TIME_START 
    ) AS b1
OUTER APPLY 
    (SELECT TOP 1 c.[DATA]
     FROM TABLE_C c
     WHERE c.TIME_START <= a.TIME_START 
       AND c.TIME_STOP >= a.TIME_START 
    ) AS c1

我的问题是TABLE_C是一个非常大的表,查询此表需要一些时间,但如果TABLE_B的结果为null,我只需要查询此表。与TABLE_B相比,TABLE_C相当小。

例如,这是查询的有效结果:

   [a.DATA] [b.DATA] [c.DATA]
1  VALUE_A  VALUE_2  NULL
2  VALUE_B  NULL     VALUE_3  

有没有办法让TABLE_C的外部适用条件为每行TABLE_B的结果,如上例所示只执行第2行?

2 个答案:

答案 0 :(得分:1)

这样的事情:

SELECT  a.DATA ,
        b1.DATA ,
        c1.DATA
FROM    TABLE_A a
        OUTER APPLY ( SELECT TOP 1
                                b.[DATA]
                      FROM      TABLE_B b
                      WHERE     b.TIME_START <= a.TIME_START
                    ) AS b1
        OUTER APPLY ( SELECT    CASE WHEN b1.[DATA] IS NULL
                                     THEN ( SELECT TOP 1
                                                    c.[DATA]
                                            FROM    TABLE_C c
                                            WHERE   c.TIME_START <= a.TIME_START
                                                    AND c.TIME_STOP >= a.TIME_START
                                          )
                                     ELSE NULL
                                END AS DATA
                    ) AS c1

或者:

   SELECT  a.DATA ,
            b1.DATA ,
            c1.DATA
    FROM    TABLE_A a
            OUTER APPLY ( SELECT TOP 1
                                    b.[DATA]
                          FROM      TABLE_B b
                          WHERE     b.TIME_START <= a.TIME_START
                        ) AS b1
            OUTER APPLY ( SELECT TOP 1
                                    c.[DATA]
                          FROM      TABLE_C c
                          WHERE     c.TIME_START <= a.TIME_START
                                    AND c.TIME_STOP >= a.TIME_START AND b1.[DATA] IS NULL
                        ) AS c1

答案 1 :(得分:1)

SELECT a.DATA, b1.DATA, c1.DATA
FROM TABLE_A a 
OUTER APPLY 
    (SELECT TOP 1 b.[DATA]
     FROM TABLE_B b
     WHERE b.TIME_START <= a.TIME_START 
    ) AS b1
OUTER APPLY 
    (SELECT TOP 1 c.[DATA]
     FROM TABLE_C c
     WHERE c.TIME_START <= a.TIME_START 
       AND c.TIME_STOP >= a.TIME_START 
       AND b1.data IS NULL
    ) AS c1

但我不知道优化器在这种情况下会做什么。是否会从C中获取所有数据,然后删除所有带有B的记录。但是,您也可以尝试复制查询:

SELECT a.DATA, b1.DATA, c1.DATA
FROM TABLE_A a 
OUTER APPLY 
    (SELECT TOP 1 b.[DATA]
     FROM TABLE_B b
     WHERE b.TIME_START <= a.TIME_START 
    ) AS b1
OUTER APPLY 
    (SELECT TOP 1 c.[DATA]
     FROM TABLE_C c
     WHERE c.TIME_START <= a.TIME_START 
       AND c.TIME_STOP >= a.TIME_START 
       AND NOT EXISTS (
       SELECT * FROM TABLE_B b WHERE  b.TIME_START <= a.TIME_START
       )
    ) AS c1