Utilisation d'un CTE dans IF EXISTS Query

8

Est-il possible de faire quelque chose de similaire à ce qui suit dans 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

J'ai essayé d'utiliser cette syntaxe et j'ai reçu une erreur. Si cela n'est pas possible, l'utilisation d'une table temporaire serait-elle la meilleure façon d'y parvenir?

Weston Sankey
la source
Pourquoi ne pas IF EXISTS (SELECT * FROM table)?
ypercubeᵀᴹ
@ypercube L'exemple que j'ai fourni n'est pas une réplique exacte de la requête avec laquelle je travaille - voir si les tables ont des lignes ne serait pas suffisant dans ce que j'essaie. Je suppose qu'il aurait été plus exact de direWHERE rn = 2
Weston Sankey
1
Ensuite, vous pourriez aussi direIF EXISTS (SELECT column FROM dbo.table GROUP BY column HAVING COUNT(*)>1)
Aaron Bertrand

Réponses:

10

Un CTE ne peut pas être utilisé comme sous-requête. Une solution de contournement serait:

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 autre serait:

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

Même si votre syntaxe proposée était valide, le EXISTScourt-circuit ne serait pas dans ce cas de toute façon, je pense (et je soupçonne que c'est pourquoi vous voudriez l'utiliser), car la fonction de fenêtre doit se matérialiser sur l'ensemble complet avant de rnpouvoir être filtré.

Aaron Bertrand
la source
4

Une autre option consiste à utiliser une variable:

DECLARE @HasRows bit = 0;

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

IF @HasRows
BEGIN
    PRINT 'True';
END
Mitch
la source
2

Je pense que vous pouvez utiliser du code comme celui-ci:

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 

Le résultat de la condition peut être stocké sous forme de variable.

Sergey Shoshin
la source