2012-10-29 4 views
-1

는 SQL 서버에는 중간 기능도 없다, 그래서 나는이 멋진 제안을 사용하고 있습니다 :모든 레코드의 중앙값을 구하는 방법은 무엇입니까?

https://stackoverflow.com/a/2026609/117700

이이 전체 데이터 세트를 통해 중간 값을 계산,하지만 난 레코드 당 평균 필요합니다. 여기

+-----------+-------------+ 
| client_id | TimesTested | 
+-----------+-------------+ 
| 214220 |   1 | 
| 215425 |   1 | 
| 212839 |   4 | 
| 215249 |   1 | 
| 210498 |   3 | 
| 110655 |   1 | 
| 110655 |   1 | 
| 110655 |   12 | 
| 215425 |   4 | 
| 100196 |   1 | 
| 110032 |   1 | 
| 110032 |   1 | 
| 101944 |   3 | 
| 1|   2 | 
| 1|   1 | 
+-----------+-------------+ 

은 내가 사용하고 쿼리 :

내 데이터 세트는

select client_id, 
    (
    SELECT 
    (
    (SELECT MAX(TimesTested) FROM 
     (SELECT TOP 50 PERCENT t.TimesTested 
     FROM counted3 t 
     where t.timestested>1 
     and CLIENT_ID=t.CLIENT_ID 
     ORDER BY t.TimesTested) AS BottomHalf) 
    + 
    (SELECT MIN(TimesTested) FROM 
     (SELECT TOP 50 PERCENT t.TimesTested 
     FROM counted3 t 
     where t.timestested>1 
     and CLIENT_ID=t.CLIENT_ID 
     ORDER BY t.TimesTested DESC) AS TopHalf) 
    )/2 AS Median 
    ) TotalAvgTestFreq 
from counted3 

group by client_id 

하지만 내 재미 데이터를주고있다 :

+-----------+------------------+ 
| client_id | median???????????| 
+-----------+------------------+ 
| 100007 |    84 | 
| 100008 |    84 | 
| 100011 |    84 | 
| 100014 |    84 | 
| 100026 |    84 | 
| 100027 |    84 | 
| 100028 |    84 | 
| 100029 |    84 | 
| 100042 |    84 | 
| 100043 |    84 | 
| 100071 |    84 | 
| 100072 |    84 | 
| 100074 |    84 | 
+-----------+------------------+ 

을 나는이를 얻을 수 있습니다 모든 client_id의 중앙값?

나는 현재 아론의 사이트에서이 멋진 쿼리를 사용하는 것을 시도하고있다 : Richardthekiwi가 지적 하듯,

select c3.client_id,(
    SELECT AVG(1.0 * TimesTested) median 
    FROM 
    (
     SELECT o.TimesTested , 
     rn = ROW_NUMBER() OVER (ORDER BY o.TimesTested), c.c 
     FROM counted3 AS o 
     CROSS JOIN (SELECT c = COUNT(*) FROM counted3) AS c 
     where count>1 
    ) AS x 
    WHERE rn IN ((c + 1)/2, (c + 2)/2) 
    ) a 
    from counted3 c3 
    group by c3.client_id 

불행히도 :

이 질문에 대한 반면 그것은 하나의 중간위한거야 중앙값 파티션 당

나는 파티션 당 중간을 얻기 위해 counted3에 참여할 수있는 방법을 알고 싶습니다>

+0

"레코드 당 중간 값"이란 무엇을 의미합니까? – Lamak

+0

@Lamak 나는 client_id에 대한 모든 값을 의미합니다. 100007 중간 값을 얻고 싶습니다. –

+0

100007에 1, 1,1,1,2,4,5,7,8,99의 시간이 있으면 중간 값이 4 –

답변

1

주 : testFreq가 int 또는 bigint 유형 인 경우 평균을 취하기 전에 캐스팅해야합니다. 그렇지 않으면 정수 나눗셈이 발생합니다. (2+5)/2 => 3 2와 5가 중간 레코드 인 경우 - 예 : AVG(Cast(testfreq as float)).

select client_id, avg(testfreq) median_testfreq 
from 
(
    select client_id, 
      testfreq, 
      rn=row_number() over (partition by CLIENT_ID 
           order by testfreq), 
      c=count(testfreq) over (partition by CLIENT_ID) 
    from tbk 
    where timestested>1 
) g 
where rn in (round(c/2,0),c/2+1) 
group by client_id; 

메디안 어느 행의 홀수의 중앙 레코드 또는 행의 짝수 개의 중앙 평균 레코드로된다. 이 조건은 rn in (round(c/2,0),c/2+1) 조건에 의해 처리되며 하나 또는 두 개의 레코드가 필요합니다.

+0

대단히 감사합니다 !!!!!!! –

1

이 시도 :

select client_id, 
    (
    SELECT 
    (
    (SELECT MAX(testfreq) FROM 
     (SELECT TOP 50 PERCENT t.testfreq 
     FROM counted3 t 
     where t.timestested>1 
     and c3.CLIENT_ID=t.CLIENT_ID 
     ORDER BY t.testfreq) AS BottomHalf) 
    + 
    (SELECT MIN(testfreq) FROM 
     (SELECT TOP 50 PERCENT t.testfreq 
     FROM counted3 t 
     where t.timestested>1 
     and c3.CLIENT_ID=t.CLIENT_ID 
     ORDER BY t.testfreq DESC) AS TopHalf) 
    )/2 AS Median 
    ) TotalAvgTestFreq 
from counted3 c3 

group by client_id 

나는 외부 CLIENT_ID 참조 및 외부 테이블에 C3 별칭을 추가했다.

+0

대단히 고맙습니다. 문제는 무엇이었을까요?하지만 불행히도이 쿼리는 15 분 동안 실행되었습니다. –

관련 문제