2016-03-01 2 views
3

Я понимаю, что мы можем переписать percentile_cont в Teradata как:Получение несколько процентилей (percentile_cont эквивалент) за один проход в Teradata

SELECT 
    part_col 
    ,data_col 
    + ((MIN(data_col) OVER (PARTITION BY part_col ORDER BY data_col ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) - data_col) 
     * (((COUNT(*) OVER (PARTITION BY part_col) - 1) * x) MOD 1)) AS percentile_cont 
FROM tab 
QUALIFY ROW_NUMBER() OVER (PARTITION BY part_col ORDER BY data_col) 
    = CAST((COUNT(*) OVER (PARTITION BY part_col) - 1) * x AS INT) + 1; 

См this very helpful discussion для получения дополнительной информации.

Понимая, что замена x на 0.90 вернет 90-й процентиль, есть ли элегантный способ продлить это и вернуть несколько процентилей за один проход?

Например, я хочу продлить этот пример и вернуть 25, 50 и 75 процентилей за один проход? Это возможно? Похоже, мне понадобится несколько заявлений QUALIFY? Аналогично, если мне нужно несколько эквивалентов GROUP BY, это похоже на прохождение большего количества столбцов в PARTITION BY?


-- SQL:2008 Equivalent pseudo-code 
SELECT 
    part_col_a 
,part_col_b 
,PERCENTILE_CONT(0.25) WITHIN GROUP (ORDER BY order_col) AS p25 
,PERCENTILE_CONT(0.50) WITHIN GROUP (ORDER BY order_col) AS p50 
,PERCENTILE_CONT(0.75) WITHIN GROUP (ORDER BY order_col) AS p75 
FROM tab 
GROUP BY 
    part_col_a 
    ,part_col_b 

ответ

3

Вы должны полностью прочитать мой блог, окончательный запрос делает именно то, что вы хотите :-)

SELECT part_col 
    ,MIN(pc25) OVER (PARTITION BY part_col) AS quartile_1 
    ,MIN(pc50) OVER (PARTITION BY part_col) AS quartile_2 
    ,MIN(pc75) OVER (PARTITION BY part_col) AS quartile_3 
FROM 
(
    SELECT 
    part_col 
    ,COUNT(*)  OVER (PARTITION BY part_col) - 1 AS N 
    ,ROW_NUMBER() OVER (PARTITION BY part_col ORDER BY data_col) - 1 AS rowno 
    ,MIN(data_col) OVER (PARTITION BY part_col ORDER BY data_col ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) - data_col AS diff 

    ,CASE 
     WHEN rowno = CAST(N * 0.25 AS INT) 
     THEN data_col +(((N * 0.25) MOD 1) * diff) 
    END AS pc25 

    ,CASE 
     WHEN rowno = CAST(N * 0.50 AS INT) 
     THEN data_col +(((N * 0.50) MOD 1) * diff) 
    END AS pc50 

    ,CASE 
     WHEN rowno = CAST(N * 0.75 AS INT) 
     THEN data_col +(((N * 0.75) MOD 1) * diff) 
    END AS pc75 
    FROM tab 
    QUALIFY rowno = CAST(N * 0.25 AS INT) 
     OR rowno = CAST(N * 0.50 AS INT) 
     OR rowno = CAST(N * 0.75 AS INT) 
) AS dt 
QUALIFY ROW_NUMBER() OVER (PARTITION BY part_col ORDER BY part_col) = 1 

 Смежные вопросы

  • Нет связанных вопросов^_^