【问题标题】:Select sequential column records and also find the longest sequence选择顺序列记录并找到最长的序列
【发布时间】:2015-09-14 11:40:51
【问题描述】:

我希望为不同的 id 获得长度大于 1 的类型列序列。

创建的表如下

 id | type 
----+------
  1 | E1
  1 | E1
  2 | A3
  3 | B2
  1 | A1
  4 | C1
  5 | C
  7 | D
  8 | D
  9 | A1
  3 | D
(11 rows)

这是我首先要实现的目标:

id | type
1  | E1
1  | E1
1  | A1
3  | B2
3  | D

上面的结果是我应该得到的类型序列 E1,E1,A1 用于 id 1 和 B2,D 用于 id 3。

我试过这个无疑是错误的:

select q1.id, q1.type 
from 
    (select row_number() over () as rowno, * from recs) q1, 
    (select row_number() over () as rowno, * from recs) q2 
where q1.rowno > q2.rowno and  q1.id = q2.id;`

它给了我类似的东西:

 id | type 
----+------
  1 | E1
  1 | A1
  1 | A1
  3 | D
(4 rows)

在此之后,我想找到最长的序列。

【问题讨论】:

标签: sql postgresql aggregate-functions amazon-redshift


【解决方案1】:

试试这个。 CTE 获取具有多个记录的 id,查询仅提取这些记录。

WITH ids_recurring_more_than_once AS
(SELECT id FROM mytable GROUP BY id HAVING COUNT(*) >1)
SELECT m.* FROM mytable m
INNER JOIN ids_recurring_more_than_once 
ON m.id = ids_recurring_more_than_once.id

“最长序列”是指重复次数最多的 id 吗?在这种情况下,将 CTE 替换为:

SELECT id FROM mytable GROUP BY id ORDER BY COUNT(*) DESC LIMIT 1

【讨论】:

  • 最长我想要序列 E1 , E1 , A1
  • 在这种情况下,只需使用 CTE 中的最后一个查询(“WITH”后括号中的语句)。而不是 m.*,你可以使用 m.type.
  • WITH ids_recurring_more_than_once AS (SELECT id FROM recs GROUP BY id HAVING COUNT() >1 order by count() desc limit 1) SELECT m.* FROM recs m INNER JOIN ids_recurring_more_than_once ON m.id = ids_recurring_more_than_once.id ;
  • 它会一直保证我的顺序正确吗?
  • 那你需要在查询的最后加上“ORDER BY type”。
【解决方案2】:

你可以使用count() over partition:

select id, typ
from (
    select *, count(*) over (partition by id) seq_len
    from recs
    ) sub
where seq_len > 1

 id | typ
----+-----
  1 | A1
  1 | E1
  1 | E1
  3 | D
  3 | B2
(5 rows)    

或聚合序列:

select *
from (
    select id, array_agg(typ) seq
    from recs
    group by 1
    ) sub
where array_length(seq, 1) > 1

 id |    seq
----+------------
  1 | {E1,E1,A1}
  3 | {B2,D}
(2 rows)    

使用最后一个查询选择最长的序列:

select id, seq, array_length(seq, 1) seq_len
from (
    select id, array_agg(typ) seq
    from recs
    group by 1
    ) sub
order by 3 desc
limit 1

 id |    seq     | seq_len
----+------------+---------
  1 | {E1,E1,A1} |       3
(1 row) 

【讨论】:

  • array_agg 听起来很棒。我会用这个。
猜你喜欢
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 2020-11-18
  • 2014-03-31
  • 1970-01-01
  • 2011-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多