我有一个需要从多个表中检索数据的查询。对于其中两个表,数据由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行?
答案 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