2010-01-11 4 views
2

j'ai cette SQL pour MS SQL Server 2008:mode Ajoutant à ce SQL

WITH CTE AS (
SELECT e_id, 
    scale, 
    ROW_NUMBER() OVER(PARTITION BY e_id ORDER BY scale ASC) AS rn, 
    COUNT(scale) OVER(PARTITION BY e_id) AS cn 
FROM waypoint.dbo.ScoreMaster 
WHERE scale IS NOT NULL 
) 
SELECT e_id, 

cast(AVG (cast(scale as decimal(5,2))) as decimal(5,3)) as [AVG], 

cast (STDEV(cast(scale as decimal(5,1))) as decimal(5,3)) as [STDDEV], 
AVG(CASE WHEN 2 * rn - cn BETWEEN 0 AND 2 THEN 
    scale END) AS FinancialMedian, 

MAX(CASE WHEN 2 * rn - cn BETWEEN 0 AND 2 THEN 
    scale END) AS StatisticalMedian 
from CTE 
GROUP BY e_id 

et je voudrais ajouter le mode. J'ai essayé des idées différentes, mais rien ne fonctionne encore ...

+0

Comment voulez-vous que votre sql se comporter quand il arrive d'exister un échantillon bimodale (avec deux modes)? Et quand il y a plus de deux modes? – kurast

Répondre

1
WITH s (e_id, scale) AS 
     (
     SELECT 1, 0.0 
     UNION ALL 
     SELECT 1, 0.1 
     UNION ALL 
     SELECT 1, 0.1 
     UNION ALL 
     SELECT 1, 0.2 
     UNION ALL 
     SELECT 1, 0.2 
     UNION ALL 
     SELECT 1, 0.3 
     ), 
     cte AS 
     (
     SELECT e_id, 
       scale, 
       ROW_NUMBER() OVER (PARTITION BY e_id ORDER BY scale ASC) AS rn, 
       COUNT(scale) OVER (PARTITION BY e_id) AS cn, 
       COUNT(*) OVER (PARTITION BY e_id, scale) AS sn 
     FROM s 
     WHERE scale IS NOT NULL 
     ) 
SELECT e_id, 
     AVG(scale), 
     (
     SELECT AVG(scale) 
     FROM cte ci 
     WHERE ci.e_id = co.e_id 
       AND ci.sn = MAX(co.sn) 
     ) AS mode 
FROM cte co 
GROUP BY 
     e_id 

Ceci sélectionnera la moyenne de toutes les échelles modales. Remplacez AVG par TOP 1 ... ORDER BY pour obtenir une échelle unique.

Notez comment nous pouvons utiliser MAX(co.sn) dans la WHERE clause :)

0

Essayez ceci:

; WITH Mean AS (
SELECT AVG(scale)/1.0 AS MeanVal 
    FROM waypoint.dbo.ScoreMaster 
WHERE scale IS NOT NULL 
), Median AS (
SELECT ((SELECT TOP 1 scale 
      FROM (SELECT TOP 50 PERCENT scale FROM waypoint.dbo.ScoreMaster WHERE scale IS NOT NULL ORDER BY scale) AS A 
      ORDER BY scale DESC) 
     + (SELECT TOP 1 scale 
      FROM (SELECT TOP 50 PERCENT scale FROM waypoint.dbo.ScoreMaster WHERE scale IS NOT NULL ORDER BY scale DESC) AS A 
      ORDER BY scale ASC))/2.0 AS MedianVal 
), Mode AS (
SELECT scale AS ModeVal 
    FROM waypoint.dbo.ScoreMaster 
WHERE scale IS NOT NULL 
GROUP BY scale 
HAVING COUNT(scale) = (SELECT TOP 1 COUNT(scale) 
          FROM waypoint.dbo.ScoreMaster 
         WHERE scale IS NOT NULL 
         GROUP BY scale 
         ORDER BY COUNT(scale) DESC) 
) 
SELECT MeanVal 
    , MedianVal 
    , ModeVal 
    FROM Mean 
    , Median 
    , Mode 

Je sais qu'il est laid , mais l'astuce est pour joindre croisé toutes les valeurs possibles sont données par Mode avec la valeur Moyenne et Médiane.

0

Ou ceci:

; WITH Mean AS (
SELECT AVG(scale)/1.0 AS MeanVal 
    FROM waypoint.dbo.ScoreMaster 
WHERE scale IS NOT NULL 
), Median AS (
SELECT ((SELECT TOP 1 scale 
      FROM (SELECT TOP 50 PERCENT scale FROM waypoint.dbo.ScoreMaster WHERE scale IS NOT NULL ORDER BY scale) AS A 
      ORDER BY scale DESC) 
     + (SELECT TOP 1 scale 
      FROM (SELECT TOP 50 PERCENT scale FROM waypoint.dbo.ScoreMaster WHERE scale IS NOT NULL ORDER BY scale DESC) AS A 
      ORDER BY scale ASC))/2.0 AS MedianVal 
), Mode AS (
SELECT AVG(scale) AS ModeVal 
    FROM waypoint.dbo.ScoreMaster 
WHERE scale IS NOT NULL 
HAVING COUNT(scale) = (SELECT TOP 1 COUNT(scale) 
          FROM waypoint.dbo.ScoreMaster 
         WHERE scale IS NOT NULL 
         GROUP BY scale 
         ORDER BY COUNT(scale) DESC) 
) 
SELECT MeanVal 
    , MedianVal 
    , ModeVal 
    FROM Mean 
    , Median 
    , Mode 

si vous voulez mode être l'AVG entre les échelles avec le nombre le plus élevé.

Questions connexes