PostgreSQL中的窗口函数

时间:2013-05-29 07:26:54

标签: sql postgresql window-functions

我有一个我的SELECT语句,我无法理解。查询如下:

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

PostgreSQL中是否有等效的rownum()? (除了使用LIMIT关键字来实现相同的结果,即。)

有人对我有什么建议吗?提前谢谢。

2 个答案:

答案 0 :(得分: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 :(得分:1)

问题出在我的查询中,即出现语法错误。 我需要的是每个category_idtype_id的前5个category_id和前5个实例以及每个sub_type_idtype_id的前5个实例。为此,我以下列方式更改了查询,最终得到了预期的输出:

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;

感谢大家的关注和帮助我。