Est-il un moyen de calculer la corrélation dans TSQL à l'aide de PLUS de Clauses au lieu de la CTE?

Disons que vous avez une table avec des colonnes, la Date, l'id de groupe, X et Y.

CREATE TABLE #sample
  (
     [Date]  DATETIME,
     GroupID INT,
     X       FLOAT,
     Y       FLOAT
  )

DECLARE @date DATETIME = getdate()

INSERT INTO #sample VALUES(@date, 1, 1,3)
INSERT INTO #sample VALUES(DATEADD(d, 1, @date), 1, 1,1)
INSERT INTO #sample VALUES(DATEADD(d, 2, @date), 1, 4,2)
INSERT INTO #sample VALUES(DATEADD(d, 3, @date), 1, 3,3)
INSERT INTO #sample VALUES(DATEADD(d, 4, @date), 1, 6,4)
INSERT INTO #sample VALUES(DATEADD(d, 5, @date), 1, 7,5)
INSERT INTO #sample VALUES(DATEADD(d, 6, @date), 1, 1,6)

et que vous voulez calculer la corrélation de X et Y pour chaque groupe. Actuellement, je utiliser d'expressions de table communes qui obtenir un peu désordonné:

;WITH DataAvgStd
     AS (SELECT GroupID,
                AVG(X)   AS XAvg,
                AVG(Y)   AS YAvg,
                STDEV(X) AS XStdev,
                STDEV(Y) AS YSTDev,
                COUNT(*) AS SampleSize
         FROM   #sample
         GROUP  BY GroupID),
     ExpectedVal
     AS (SELECT s.GroupID,
                SUM(( X - XAvg ) * ( Y - YAvg )) AS ExpectedValue
         FROM   #sample s
                JOIN DataAvgStd das
                  ON s.GroupID = das.GroupID
         GROUP  BY s.GroupID)
SELECT das.GroupID,
       ev.ExpectedValue / ( das.SampleSize - 1 ) / ( das.XStdev * das.YSTDev )
       AS
       Correlation
FROM   DataAvgStd das
       JOIN ExpectedVal ev
         ON das.GroupID = ev.GroupID

DROP TABLE #sample  

Il semble qu'il devrait y avoir un moyen de l'utiliser SUR et PARTITION pour ce faire d'un seul coup, sans aucune sous-requêtes. Idéalement TSQL aurait une fonction de sorte que vous pourriez écrire:

SELECT GroupID, CORR(X, Y) OVER(PARTITION BY GroupID)
FROM #sample
GROUP BY GroupID
Je serais curieux de voir si quelqu'un arrive avec une solution viable, cependant, j'ai toujours tirer toutes mes données à la couche de gestion et d'effectuer des corrélations. Nous réalisons également ce que nous appelons des "corrélations négatives" - où l'on ignorer les valeurs positives et les inclure uniquement des valeurs négatives, il serait également intéressant de voir si c'était viable en SQL.
Le code que vous avez posté n'a pas exécuter pour diverses raisons. Je l'ai changé donc il va effectivement vous voudrez peut-être vérifier qu'il ne fait toujours ce que vous attendiez...
Si X ou Y sont les valeurs null, vous devez remplacer "#exemple" avec "DE l' #exemple OÙ X EST NON NUL, ET Y n'EST PAS NUL", sinon vous pouvez vous retrouver avec la mauvaise corrélation

OriginalL'auteur bpeikes | 2011-08-03