如何防止CTE执行直到达到或不存在

我有一个使用某些CTEs (Common Table Expressions)的SQL Server查询。它有两个表可供选择数据。这两个表的结构相同,但不是必需的数据。该查询将首先从table_a中进行选择,如果未获取任何行,则它将从table_b中进行选择。查询是这样的:

;WITH cte_a AS (
  ...
),cte_b AS (
  ...
) 
SELECT * 
FROM table_a
INNER JOIN cte_a ON condition_a
OR NOT EXISTS (
  SELECT *
  FROM table_b
  INNER JOIN cte_b ON condition_b
)

我目前遇到的问题是,无论cte_b是否返回任何行,都将始终执行table_a。这对我来说不是很理想;我想让cte_b 仅在以下情况下执行:table_a的子查询不返回任何行。

我尝试将cte_b移到table_b的子查询之前,

;WITH cte_a AS (
  ...
)
SELECT * 
FROM table_a
INNER JOIN cte_a ON condition_a
OR NOT EXISTS (
  ;WITH cte_b AS (
    ...
  ) 
  SELECT *
  FROM table_b
  INNER JOIN cte_b ON condition_b
)

但是,IDE抱怨。我认为这不是应该使用CTE的方式。

superlinkai 回答:如何防止CTE执行直到达到或不存在

创建用于存储数据的临时表-将查询分为两个单独的INSERT语句,其中第二个语句仅在第一个查询完成后不填充任何数据的情况下执行。像这样:

CREATE TABLE #TEmp
(

);


;WITH cte_a AS (
  ...
)
INSERT INTO #TEmp
SELECT * 
FROM table_a
INNER JOIN cte_a ON condition_a

IF NOT EXISTS(SELECT 1 FROM #TEmp)
BEGIN;

INSERT INTO #TEmp
SELECT * 
FROM table_a
WHERE NOT EXISTS (
  SELECT *
  FROM table_b
  INNER JOIN cte_b ON condition_b
)
,

这是CTE的本质。

最好的办法是不使用CTE并使用联接,但我认为您不能。

我建议您尝试使用子查询,以便引擎可以一次处理所有问题。

,

我会用一个联合来表述,然后在第一个CTE有任何结果的情况下排除cte_b上联合的后半部分。

;WITH cte_a AS (
    ...
),cte_b AS (
    ...
)

SELECT * 
FROM table_a
INNER JOIN cte_a ON condition_a
UNION ALL
SELECT *
FROM table_b
INNER JOIN cte_b ON condition_b
WHERE NOT EXISTS (
    SELECT 1
    FROM table_a
    INNER JOIN cte_a ON condition_a
)
,
;WITH    cte1 AS
        (
        ....
        ),cte2 AS
        (
        ...
        )

SELECT * 
FROM table_a
INNER JOIN cte_a ON condition_a ---Choose Your Condition...

UNION ALL

SELECT *
FROM table_b
INNER JOIN cte_b ON condition_b ---Choose Your Condtion....
WHERE NOT EXISTS (SELECT * FROM cte2)

注意:-

CTE之后必须有一个引用了部分或全部SELECT,INSERT,UPDATE,or DELETE的{​​{1}}语句。

本文链接:https://www.f2er.com/3154787.html

大家都在问