How to get mean ,median , mode and range in a single select query?

后端 未结 3 1205
死守一世寂寞
死守一世寂寞 2021-01-27 09:06

I\'m trying to get mean, median, mode and range for a set of values in a table. I was able to get the average but median, range and mode I\'m getting a wrong one.

Below

相关标签:
3条回答
  • 2021-01-27 09:44

    I imagine that you may rather want to do something like this:

    select dbo.Median(DataValues_AttributeValue)
    from ...
    

    There is no slick way to get the median or mode in a manner similar to using the native aggregates such as avg, max, min, max, etc. However, you may want to try a .NET CLR aggregate implementation where you implement the median and mode in, for example, C# if you want something elegant, e.g. like the above code snippet.

    This is what I've done in the past.

    0 讨论(0)
  • 2021-01-27 09:51

    Not sure if this will help, but here is some sql which allows me generate some stats (..., mean, median, mode,..) within a group by

    • cteBase would be your core data (non-aggregated or groupded)
    • cteMedian would generate the median of cteBase
    • cteMode would calculate the mode of cteBase

    I am calculated only one measure, but I suspect it can easily be expanded Where I have "GrpByYear", this would have to be expanded into your compound fields.

    ;with cteBase as (
         Select RowNr=Row_Number() over (Partition By Year(TR_Date) Order By Year(TR_Date),TR_Y10)
               ,GrpByYear = Year(TR_Date)
               ,Measure = TR_Y10
         From [Chinrus-Series].[dbo].[DS_Treasury_Rates]
         Where Year(TR_Date)>2014
        )
        ,cteMedian as (Select A.GrpByYear,Measure From cteBase A Join (Select GrpByYear,RowNr=Max(RowNr)/2 from cteBase Group by GrpByYear) B on (A.GrpByYear=B.GrpByYear and A.RowNr=B.RowNr))
        ,cteMode   as (Select * from (Select RowNr=Row_Number() over (Partition By GrpByYear Order by Count(*) Desc),GrpByYear,Measure,Hits=count(*) From cteBase Group by GrpByYear,Measure) A Where RowNr=1)
        Select A.GrpByYear
              ,RecordCount   = Count(*)
              ,DistinctCount = Count(Distinct A.Measure)
              ,SumTotal      = Sum(A.Measure)
              ,Minimum       = Min(A.Measure)
              ,Maximum       = Max(A.Measure)
              ,Mean          = Avg(A.Measure)
              ,Median        = Max(B.Measure)
              ,Mode          = Max(C.Measure)
              ,StdDev        = STDEV(A.Measure)
         From cteBase A
         Join cteMedian B on A.GrpByYear=B.GrpByYear
         Join cteMode   C on A.GrpByYear=C.GrpByYear
         Group By A.GrpByYear
         Order By A.GrpByYear
    
    
    Year    RecordCount DistinctCount   SumTotal    Minimum Maximum Mean    Median  Mode    StdDev
    2016    110         43              204.82      1.63    2.25    1.862   1.84    1.83    0.128568690811108
    2015    251         69              536.71      1.68    2.50    2.1382  2.16    2.20    0.1662836533952
    
    0 讨论(0)
  • 2021-01-27 10:03

    In SQL 2012 or later, it's often easier to use the percentile_cont function to calculate the median. It looks like the rest of your question has already been addressed, but I thought you'd want to know about this option as well.

    https://msdn.microsoft.com/en-us/library/hh231473.aspx

    0 讨论(0)
提交回复
热议问题