문제

우선, I5/OS V5R4 용 DB2에서 실행 중입니다. row_number (), rank () 및 공통 테이블 표현식이 있습니다. 그래요 ~ 아니다 최고 N % 또는 제한 오프셋이 있습니다.

내가 작업하고있는 실제 데이터 세트는 설명하기 어렵 기 때문에 기둥이있는 날씨 기록 테이블이 있다고 가정 해 봅시다. (city, temperature, timestamp). 중앙값을 각 그룹의 평균과 비교하고 싶습니다. (city).

이것은 전체 테이블 집계에 대한 중앙값을 얻는 가장 깨끗한 방법이었습니다. IBM Redbook에서 적응했습니다 여기:

WITH base_t AS
( SELECT temp, row_number() over (order by temperature) AS rownum FROM t ),
count_t AS
( SELECT COUNT(temperature) + 1 AS base_count FROM base_t ),
median_t AS
( SELECT temperature FROM base_t, count_t
  WHERE rownum in (FLOOR(base_count/2e0), CEILING(base_count/2e0)) )
SELECT DECIMAL(AVG(temperature),10,2) AS median FROM median_t

그것은 단일 행을 되 찾는 데 효과적이지만 그룹화에 떨어지는 것 같습니다. 개념적으로 이것은 내가 원하는 것입니다.


SELECT city, AVG(temperature), MEDIAN(temperature) FROM ...

city           | mean_temp       | median_temp       
===================================================
'Minneapolis'  | 60              | 64
'Milwaukee'    | 65              | 66
'Muskegon'     | 70              | 61

나를 어리석게 보이게하는 대답이있을 수 있지만, 나는 정신적 인 블록을 가지고 있으며 이것은 지금 일할 #1 일이 아닙니다. 가능한 것처럼 보이지만 큰 테이블이기 때문에 매우 복잡한 것을 사용할 수 없으며 집계되는 열을 사용자 정의 할 수 있기를 원합니다.

도움이 되었습니까?

해결책

SQL Server에서 COUNT (*)와 같은 Agreagate 기능은 그룹에 의해 분할 및 계산 될 수 있습니다. 나는 참조 된 Redbook을 빠르게 살펴 보았고 DB2가 동일한 기능을 갖는 것처럼 보입니다. 그러나 그렇지 않다면, 이것은 작동하지 않습니다.

create table TemperatureHistory 
    (City varchar(20)
    , Temperature decimal(5, 2)
    , DateTaken datetime)

insert into TemperatureHistory values ('Minneapolis', 61, '20090101')
insert into TemperatureHistory values ('Minneapolis', 59, '20090102')

insert into TemperatureHistory values ('Milwaukee', 65, '20090101')
insert into TemperatureHistory values ('Milwaukee', 65, '20090102')
insert into TemperatureHistory values ('Milwaukee', 100, '20090103')

insert into TemperatureHistory values ('Muskegon', 80, '20090101')
insert into TemperatureHistory values ('Muskegon', 70, '20090102')
insert into TemperatureHistory values ('Muskegon', 70, '20090103')
insert into TemperatureHistory values ('Muskegon', 20, '20090104')

; with base_t as
    (select city
        , Temperature
        , row_number() over (partition by city order by temperature) as RowNum
        , (count(*) over (partition by city)) + 1 as CountPlusOne 
    from TemperatureHistory)
select City
    , avg(Temperature) as MeanTemp
    , avg(case 
        when RowNum in (FLOOR(CountPlusOne/2.0), CEILING(CountPlusOne/2.0)) 
            then Temperature
            else null end) as MedianTemp
from base_t 
group by City
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top