2017-02-10 6 views
0

Я пытаюсь вычислить процентили, используя функцию percentile_cont() в PostgreSQL, используя общие табличные выражения. Цель состоит в том, чтобы найти первые 1% счетов в отношении их балансов (здесь называется сумма). Моя логика, чтобы найти 99th процентиль, которая будет возвращать те, чьи счета сальдо больше, чем 99% от своих сверстников (и, таким образом, находя 1 percenters)Невозможно получить Percentile_Cont() для работы в Postgresql

Вот мой запрос

--ranking subquery works fine 
with ranking as(
     select a.lname,sum(c.amount) as networth from customer a 
     inner join 
     account b on a.customerid=b.customerid 
     inner join 
     transaction c on b.accountid=c.accountid 
     group by a.lname order by sum(c.amount) 
) 
select lname, networth, percentile_cont(0.99) within group 
order by networth over (partition by lname) from ranking ; 

Я держать получение следующая ошибка.

ERROR: syntax error at or near "order" 
LINE 2: ...ame, networth, percentile_cont(0.99) within group order by n.. 

Я думаю, что, возможно, я забыл о закрывающей скобе и т. Д., Но я не могу понять, где. Я знаю, что это может быть что-то с ключевым словом order, но я не уверен, что делать. Не могли бы вы помочь мне исправить эту ошибку?

+0

. , Ваш исходный запрос не имеет смысла. Вы группируете 'lname', а затем используете это для раздела для' networth'. Существует только одна строка, поэтому 99-й процентиль не имеет смысла. Возможно, вы захотите задать другой вопрос с образцами данных и желаемыми результатами. –

ответ

1

Вам не хватает скобок в части within group (order by x).

Попробуйте это:

with ranking 
as (
    select a.lname, 
     sum(c.amount) as networth 
    from customer a 
    inner join account b on a.customerid = b.customerid 
    inner join transaction c on b.accountid = c.accountid 
    group by a.lname 
    order by networth 
    ) 
select lname, 
    networth, 
    percentile_cont(0.99) within group (
     order by networth 
     ) over (partition by lname) 
from ranking; 
+0

Я получаю подобную ошибку, когда я пытаюсь это сделать - ОШИБКА: синтаксическая ошибка в точке или рядом "(" LINE 13: percentile_cont (0.99) внутри группы ( – Avi

+1

@Avi, что является полным сообщением об ошибке? разрешено для функции percentile_cont *? – GurV

+0

Это полное сообщение - ERROR: синтаксическая ошибка в точке или рядом "(" LINE 1: ...) как networth, percentile_cont (0.99) внутри группы (по заказу ... – Avi

2

Я хочу, чтобы указать на то, что вам не нужно подзапрос для этого:

select c.lname, sum(t.amount) as networth, 
     percentile_cont(0.99) within group (order by sum(t.amount)) over (partition by lname) 
from customer c inner join 
    account a 
    on c.customerid = a.customerid inner join 
    transaction t 
    on a.accountid = t.accountid 
group by c.lname 
order by networth; 

Кроме того, при использовании псевдонимов таблиц (которые должны быть всегда), Сокращения таблиц намного проще, чем произвольные буквы.

+0

Я получаю после ошибки, когда я это пытаюсь. BTW Я запускаю postgres 9.3.15. Я не знаю, помогает ли это. ERROR: ошибка синтаксиса в точке или рядом "(" LINE 1: ...) как networth, percentile_cont (0.99) в пределах группы (упорядочение по .. – Avi

+0

@Avi. Проходит ли оно без 'percentile_cont()'? –

+0

Нет, это не так. – Avi

0

Это тоже сработало.

Оказывается, percentile_cont не поддерживается в postgres 9.3, только в 9.4+.

https://www.postgresql.org/docs/9.4/static/release-9-4.html

Таким образом, вы должны использовать что-то вроде этого:

with ordered_purchases as (
    select 
     price, 
     row_number() over (order by price) as row_id, 
     (select count(1) from purchases) as ct 
    from purchases 
) 

select avg(price) as median 
from ordered_purchases 
where row_id between ct/2.0 and ct/2.0 + 1 

Это уход запрос о https://www.periscopedata.com/blog/medians-in-sql (раздел: "Медиана на Postgres")