5

I need to find the median of a column and the answer needs to be rounded to 4 decimal places. Since sql server doesn't have the "MEDIAN()" function, I needed to get the smallest number from the top 50% of the list and the biggest of the bottom 50% and then divide by 2.

I tried to do it like this:

SELECT(
    (SELECT CAST(ROUND(MAX(LAT_N), 4) AS DECIMAL(8, 4)) 
        FROM (SELECT TOP 50 PERCENT LAT_N FROM STATION ORDER BY LAT_N ASC) AS Bottom1)
    + (SELECT CAST(ROUND(MIN(LAT_N), 4) AS DECIMAL(8, 4))
        FROM (SELECT TOP 50 PERCENT LAT_N FROM STATION ORDER BY LAT_N DESC) AS Top1)) / 2;

But the result is 5.323200 instead of 5.3232.

I also tried this:

SELECT(
    (SELECT CAST(ROUND(MAX(LAT_N), 4) AS DECIMAL(8, 4)) 
        FROM (SELECT TOP 50 PERCENT (LAT_N / 2) AS LAT_N FROM STATION ORDER BY LAT_N ASC) AS Bottom1)
    + (SELECT CAST(ROUND(MIN(LAT_N), 4) AS DECIMAL(8, 4))
        FROM (SELECT TOP 50 PERCENT (LAT_N / 2) AS LAT_N FROM STATION ORDER BY LAT_N DESC) AS Top1));

This answer seems to be close, but by dividing both the min and the max, I end up losing 0.0001 which makes the answer wrong.

How can I fix either of the ways I'm trying to do it in order to get a median from a table. Or is there another way to do it?

4
  • 1
    "But the result is 5.323200 instead of 5.3232." 5.323200 and 5.3232 are the same value, so what is your point? If you only want the value accurate to 4 decimal places then CAST/CONVERT to a decimal with the appropriate scale.
    – Thom A
    Commented Oct 28, 2022 at 12:08
  • Depending on the version of SQL Server, you can install the "R" language and then use that in your queries. With that, you get a median function. Commented Oct 28, 2022 at 12:11
  • 1
    SQL Server doesn't have MEDIAN, but it does have PERCENTILE_CONT. The median is PERCENTILE_CONT(0.5). Commented Oct 28, 2022 at 12:12
  • @Larnu I know that they are the same number. The problem is that I'm not doing it for my own DB, but I do it for an exercise on a website that counts it as a mistake. The CAST**/**CONVERT with appropriate scale is done as you can see with CAST, at least with my knowledge, which is why I asked if there was a better way to make the code work. Commented Oct 28, 2022 at 12:15

1 Answer 1

4

I have been reading the T-SQL Querying by Itzik Ben-Gan and recently came across the BI section. I believe this is what you want. This is how he explains to get the median. He calls this the financial median. Your other option is to look at the PERCENTILE_DISC instead of the PERCENTILE_CONT as shown below.

CREATE TABLE #Test (
    [Id] INT IDENTITY(1,1) CONSTRAINT PK_Id PRIMARY KEY,
    [Cost] DECIMAL(19,4) NOT NULL
);

INSERT INTO #Test([Cost])
VALUES (5),(10),(15);

SELECT DISTINCT
PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY [Cost]) OVER () AS median
FROM #Test
1
  • 1
    Thank you, exactly what I needed, just added a Cast, so I can only get 4 decimal places. Commented Oct 28, 2022 at 12:20

Not the answer you're looking for? Browse other questions tagged or ask your own question.