2013-05-29 4 views
1

У меня есть оператор SELECT, который я просто не могу понять. Запрос выглядит следующим образом:Функция окна в PostgreSQL

SELECT 
    count(1), 
    interaction_type_id 
FROM 
    tibrptsassure.d_interaction_sub_type 
GROUP BY 
    interaction_type_id 
HAVING 
    count(interaction_type_id) > 1 
ORDER BY 
count(interaction_type_id) DESC 
LIMIT 5; 

Поскольку мое приложение не поддерживает использование LIMIT ключевого слова, я попытался изменить свой запрос, используя функцию rank() как так:

SELECT 
interaction_type_id, 
rank() OVER (PARTITION BY interaction_type_id ORDER BY count(interaction_type_id) 
DESC) 
FROM 
tibrptsassure.d_interaction_sub_type; 

Однако этот путь я закончилась со следующим сообщением об ошибке:

ERROR: column "d_interaction_sub_type.interaction_type_id" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT interaction_type_id, rank() OVER (PARTITION BY inter...  
        ^
    ********** Error ********** 

ERROR: column "d_interaction_sub_type.interaction_type_id" must appear in the GROUP BY clause or be used in an aggregate function 
SQL state: 42803 
Character: 9 

есть ли эквивалент rownum() в PostgreSQL? (Помимо использования ключевого слова LIMIT для достижения того же результата, то есть.)

У кого-нибудь есть предложения для меня? Заранее спасибо.

+0

Что это значит: «Мое приложение * не поддерживает ограничение»? Язык программирования, PostgreSql, ORM? Рассмотрите возможность предоставления демонстрации SQLFiddle и форматирования ваших SQL-команд в качестве источника. – Beryllium

+0

Intelliview Nxt .. Портал, который мы используем для создания отчетов. Это не поддерживает функцию ограничения. – Nancy

+1

Но он * делает * поддержку * окно aggegate функции * (более ... раздел by ...)? Таким образом, вы можете изменить запрос на использование агрегатных функций, но не используя лимит? Другими словами, что вы можете использовать в своем запросе? – Beryllium

ответ

1

Тест ли следующие работы (это стандартный синтаксис PostgreSQL и должен работать):

with 
t as (
    select 1 as id union all 
    select 1 as id union all  
    select 2 union all 
    select 2 union all  
    select 3) 

select 
    id 
from 
    t 
group by 
    id 
having 
    count(id) > 1 
order by 
    id desc 
limit 1 

Если это работает, то у вас есть какие-то проблемы синтаксиса. Если это не работает, у вас есть другая проблема - возможно, используемое вами программное обеспечение ограничено каким-то действительно странным образом.

Вы также можете использовать row_number(), но это не очень эффективный способ:

with 
t as (
    select 1 as id union all 
    select 1 as id union all  
    select 2 union all 
    select 2 union all  
    select 3) 

, u as (
    select 
     id, 
     count(*) 
    from 
     t 
    group by 
     id 
    ) 

, v as (
    select 
     *, 
     row_number() over(order by id) c 
    from 
     u 
    ) 

select 
    * 
from 
    v 
where 
    c < 2 
1

Проблема была в моем запросе, то есть была ошибка синтаксиса. То, что мне было нужно, было топ 5 category_id и 5 лучших экземпляров type_id в каждом category_id и 5 лучших экземплярах sub_type_id в каждом type_id. Для достижения этой цели, я изменил запрос следующим образом и наконец получил ожидаемый результат:

SELECT * FROM (
SELECT t1.int_subtype_key, t2.interaction_sub_type_desc, interaction_category_id, 
interaction_type_id, interaction_sub_type_id, count(interaction_sub_type_id) AS 
subtype_cnt, 
rank() 
over (PARTITION BY interaction_category_id, interaction_type_id ORDER BY 
count(interaction_sub_type_id) DESC) AS rank 
FROM tibrptsassure.f_cc_call_analysis t1 INNER JOIN 
tibrptsassure.d_interaction_sub_type t2 ON t1.int_cat_key = t2.intr_catg_ref_nbr 
AND t1.int_subtype_key = t2.intr_sub_type_ref_nbr INNER JOIN 
tibrptsassure.d_calendar t3 ON t1.interaction_date = t3.calendar_date GROUP BY 
t2.interaction_sub_type_desc, t1.int_subtype_key, interaction_category_id, 
interaction_type_id, interaction_sub_type_id) AS sub_type 
WHERE rank <= 5; 

Спасибо всем за внимание и помочь мне с этим.

+0

Итак, в основном вы сдались с использованием подзапрос, а не то, что я знаю иначе. –