Использование CTE в IF EXISTS Query

8

Можно ли сделать что-то похожее на следующее в SQL Server 2012?

IF EXISTS (
    WITH DATA AS (
        SELECT *, 
        ROW_NUMBER() OVER(PARTITION BY column ORDER BY Column) AS rn
        FROM table )
    SELECT *
    FROM DATA
    WHERE rn = 2 )
BEGIN
...
END

Я попытался использовать этот синтаксис и получил ошибку. Если это невозможно, будет ли использование временной таблицы лучшим способом для этого?

Уэстон Санки
источник
Почему нет IF EXISTS (SELECT * FROM table)?
ypercubeᵀᴹ
@ypercube Приведенный мною пример не является точной копией запроса, с которым я работаю - проверки того, что в таблицах есть строки, будет недостаточно в том, что я пытаюсь сделать. Я думаю, это было бы более точно сказатьWHERE rn = 2
Уэстон Сэнки
1
Тогда вы могли бы также сказатьIF EXISTS (SELECT column FROM dbo.table GROUP BY column HAVING COUNT(*)>1)
Аарон Бертран

Ответы:

10

CTE нельзя использовать в качестве подзапроса. Один обходной путь будет:

IF EXISTS 
(
  SELECT 1 FROM 
  (
    SELECT ROW_NUMBER() OVER(PARTITION BY column ORDER BY Column) AS rn
    FROM table
  ) AS DATA 
  WHERE rn = 2
)
BEGIN
  ...
END

Другой будет:

IF EXISTS (SELECT 1 FROM dbo.table GROUP BY column HAVING COUNT(*) > 1)
BEGIN
  ...
END

EXISTSЯ думаю, что даже если предложенный вами синтаксис действителен, в этом случае не будет короткого замыкания (и я подозреваю, что именно поэтому вы и захотите его использовать), поскольку оконная функция должна материализоваться во всем наборе, прежде чем rnсможет быть отфильтрованным.

Аарон Бертран
источник
4

Другой вариант - использовать переменную:

DECLARE @HasRows bit = 0;

WITH foo as 
(
    ...
)
SELECT TOP(1) @HasRows = 1
FROM foo;

IF @HasRows
BEGIN
    PRINT 'True';
END
Митч
источник
2

Я думаю, что вы можете использовать такой код:

IF OBJECT_ID('tempdb..#data1') IS NOT NULL
            BEGIN 
                DROP TABLE #data1;
            END;

           CREATE TABLE #data1 (
id INT
)

IF OBJECT_ID('tempdb..#data2') IS NOT NULL
                BEGIN 
                    DROP TABLE #data2;
                END;

CREATE TABLE #data2 (
id INT
)

INSERT INTO #data1
VALUES (1), (2), (3), (4)

INSERT INTO #data2
VALUES (4), (5)

DECLARE @result INT = 0;


;WITH result_set AS (
SELECT id FROM #data1
  UNION 
SELECT id FROM #data2
)
SELECT @result = 1 FROM result_set WHERE id = 5 --6

IF (@result = 1)
BEGIN 
SELECT 'YAHOO'
END 

Результат условия может быть сохранен как переменная.

Сергей Шошин
источник