Utilizzo di un CTE nelle query IF EXISTS


8

È possibile fare qualcosa di simile al seguente in 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

Ho provato a usare questa sintassi e ho ricevuto un errore. Se ciò non fosse possibile, utilizzare una tabella temporanea sarebbe il modo migliore per ottenere questo risultato?



Perché no IF EXISTS (SELECT * FROM table)?
ypercubeᵀᴹ

@ypercube L'esempio che ho fornito non è una replica esatta della query con cui sto lavorando - vedere se le tabelle hanno righe non sarebbe sufficiente in quello che sto tentando. Immagino che sarebbe stato più accurato dirloWHERE rn = 2
Weston Sankey il

1
Quindi potresti anche direIF EXISTS (SELECT column FROM dbo.table GROUP BY column HAVING COUNT(*)>1)
Aaron Bertrand

Risposte:


10

Un CTE non può essere utilizzato come sottoquery. Una soluzione alternativa sarebbe:

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

Un altro sarebbe:

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

Anche se la tua sintassi proposta fosse valida, EXISTSin quel caso non avrebbe cortocircuito, penserei (e sospetto che sia per questo che vorresti usarlo), poiché la funzione finestra deve materializzarsi sull'intero set prima che rnpotrebbe essere filtrato.


4

Un'altra opzione è utilizzare una variabile:

DECLARE @HasRows bit = 0;

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

IF @HasRows
BEGIN
    PRINT 'True';
END

2

Penso che tu possa usare il codice in questo modo:

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 

Il risultato della condizione può essere memorizzato come variabile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.