Usar un CTE en la consulta IF EXISTS

8

¿Es posible hacer algo similar a lo siguiente en 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

Intenté usar esta sintaxis y recibí un error. Si esto no es posible, ¿usar una tabla temporal sería la mejor manera de lograr esto?

Weston Sankey
fuente
¿Por qué no IF EXISTS (SELECT * FROM table)?
ypercubeᵀᴹ
@ypercube El ejemplo que proporcioné no es una réplica exacta de la consulta con la que estoy trabajando: ver si las tablas tienen filas no sería suficiente en lo que estoy intentando. Supongo que hubiera sido más exacto decirloWHERE rn = 2
Weston Sankey
1
Entonces también podría decirIF EXISTS (SELECT column FROM dbo.table GROUP BY column HAVING COUNT(*)>1)
Aaron Bertrand

Respuestas:

10

Un CTE no se puede usar como una subconsulta. Una solución alternativa sería:

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

Otro sería:

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

Incluso si su sintaxis propuesta fuera válida, de EXISTStodos modos no se produciría un cortocircuito en ese caso, creo (y sospecho que es por eso que querría usarla), ya que la función de ventana debe materializarse en todo el conjunto antes de que rnpueda ser filtrado

Aaron Bertrand
fuente
4

Otra opción es usar una variable:

DECLARE @HasRows bit = 0;

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

IF @HasRows
BEGIN
    PRINT 'True';
END
Mitch
fuente
2

Creo que puedes usar un código como este:

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 

El resultado de la condición se puede almacenar como una variable.

Sergey Shoshin
fuente