2016-03-21 6 views
0

Ich bin mit SQL Server 2014SQL - Filtern innerhalb einer Fensterfunktion

Ich versuche, indem der Durchschnitt aller Werte in der 90. Perzentile einer Gruppe etwas Rauschen in einem Datensatz zu entfernen. Hier ist die Abfrage:

SELECT 
    DISTINCT EventLocation, 
    PERCENTILE_CONT(.90) 
     WITHIN GROUP (ORDER BY (DATEDIFF(MINUTE, StartTime, EndTime)) ASC) 
     OVER (PARTITION BY EventLocation) 
     AS 'P90', 
    AVG(DATEDIFF(MINUTE, StartTime, EndTime)) 
     OVER (PARTITION BY EventLocation) 
     AS 'Mean' 
    FROM MyTable 
    ORDER BY N DESC 

Momentan gibt es 2 berechnete Spalten:

  • Den 90. Perzentil-Wert (von PARTITION Bevölkerung)
  • Der Mittelwert (von PARTITION Bevölkerung)

Ich möchte eine weitere Spalte hinzufügen für:

  • Der Mittelwert des Wertes (in einer PARTITION Bevölkerung) < = 90. Perzentil-Wert (diese PARTITION Bevölkerung)

Etwas wie:

AVG(DATEDIFF(MINUTE, StartTime, EndTime)) 
    OVER (PARTITION BY EventLocation) 
    HAVING (DATEDIFF(MINUTE, StartTime, EndTime) <= [ 90th percentile value ]) 
    AS 'Mean90' 

bin ich nicht ganz sicher, wie man sich diesem annähert, da es auf den 90. Perzentilwert verweist, der gerade in P90 ... dififed wurde ... vielleicht eine anwenderdefinierte Funktion, die gruppenweise angewendet wird, mehrere Tabellen erzeugt und sie verbindet, oder etwas anderes.

+0

Wenn Sie SQL Server 2014 mit dieser Frage verwenden, haben Sie das Tag mysql? – scaisEdge

+1

Ich denke, Sie müssen eine Unterabfrage oder CTE dafür verwenden. –

Antwort

0

Wie Gordon sagte, ist ein CTE ein gängiger Weg, um ein Problem wie dieses zu lösen. Speichern Sie die Ergebnisse Ihrer ursprünglichen Abfrage im CTE, wählen Sie dann den Inhalt des CTE aus und fügen Sie die gewünschte Arbeit mit den von Ihnen definierten Spaltenaliasen hinzu.

;WITH IntermediateResults AS (
    SELECT 
     DISTINCT EventLocation, 
     PERCENTILE_CONT(.90) 
      WITHIN GROUP (ORDER BY (DATEDIFF(MINUTE, StartTime, EndTime)) ASC) 
      OVER (PARTITION BY EventLocation) 
      AS 'P90', 
     AVG(DATEDIFF(MINUTE, StartTime, EndTime)) 
      OVER (PARTITION BY EventLocation) 
      AS 'Mean' 
    FROM MyTable 
    ORDER BY N DESC 
) 

SELECT 
    *, 
    AVG(DATEDIFF(MINUTE, StartTime, EndTime)) 
     OVER (PARTITION BY EventLocation) 
     HAVING (DATEDIFF(MINUTE, StartTime, EndTime) <= P90) 
     AS 'Mean90' 
FROM IntermediateResults