遍历 table 中的组

Iterating over groups in table

我有以下数据:

cte1
===========================
m_ids    |p_id       |level
---------|-----------|-----
{123}    |98         |1
{123}    |111        |2
{432,222}|215        |1
{432,222}|215        |1
{432,222}|240        |2
{432,222}|240        |2
{432,222}|437        |3
{432,222}|275        |3

我必须执行以下操作:

  1. 通过以下算法提取p_id

    1. 对于具有相同 m_ids
    2. 的每一行
    3. 每组:
      2.I。按 p_id
      对记录进行分组 2.I我。按 level
      排序 desc 记录 2.I二. Select p_id 精确计数为 m_ids 长度且最大 level

到目前为止,我没能完全写出这个算法,但我在最后一部分写了这个(可能我得到的地方是错误的array_length):

SELECT id 
FROM   grouped_cte1 
GROUP  BY id, 
          level 
HAVING Count(*) = array_length(grouped_cte1.m_ids, 1) 
ORDER  BY level DESC 
LIMIT  1 

其中 m_ids={123}grouped_cte1

m_ids    |p_id       |level
---------|-----------|-----
{123}    |98         |1
{123}    |111        |2

m_ids={432,222}

m_ids    |p_id       |level
---------|-----------|-----
{432,222}|215        |1
{432,222}|215        |1
{432,222}|240        |2
{432,222}|240        |2
{432,222}|437        |3
{432,222}|275        |3

等等

2) 将 p.1 中的查询与以下内容结合起来。以下为每个 m_ids 提取 p_idlevel=1

select m_ids, p_id from cte1 where level=1 --also selecting m_ids for joining later`

结果如下:

m_ids    |p_id
---------|----
{123}    |98  
{432,222}|215   

理想结果:

m_ids    |result_1   |result_2
---------|-----------|--------
{123}    |111        |98
{432,222}|240        |215

所以谁能帮我解决算法的第一部分(可选)将它与第二部分结合在一个查询中部分?

编辑: 到目前为止我失败了:
1. 通过 m_ids 将呈现的 table 分解为子 table,同时对其进行迭代。
2. 对query中对应的行进行array_length(grouped_cte1.m_ids, 1)的计算

对于查询的第一部分,您在正确的轨道上,但您需要更改分组逻辑,然后再次加入 table 以按每个 [=46] 的最高级别过滤掉它=] 你可以使用 DISTINCT ON 子句结合适当的排序:

select 
  distinct on (t.m_ids)
  t.m_ids, t.p_id, t.level
from cte1 t
join (
  select
    m_ids,
    p_id
  from cte1
  group by m_ids, p_id
  having count(*) = array_length(m_ids, 1)
  ) as g using (m_ids, p_id)
order by t.m_ids, t.level DESC;

这会给你:

   m_ids   | p_id | level
-----------+------+-------
 {123}     |  111 |     2
 {432,222} |  240 |     2

然后与第二个查询结合使用(使用 FULL JOIN 用于显示目的,当第一个查询缺少此类条件时),我通过添加 distinct 进行了修改,因为可以(并且实际上)超过m_ids, p_id 的一条记录与第一级配对看起来像:

select 
  coalesce(r1.m_ids, r2.m_ids) as m_ids,
  r1.p_id AS result_1,
  r2.p_id AS result_2
from (
  select 
    distinct on (t.m_ids)
    t.m_ids, t.p_id, t.level
  from cte1 t
  join (
    select
      m_ids,
      p_id
    from cte1
    group by m_ids, p_id
    having count(*) = array_length(m_ids, 1)
    ) as g using (m_ids, p_id)
  order by t.m_ids, t.level DESC
  ) r1
full join (
  select distinct m_ids, p_id
  from cte1
  where level = 1
  ) r2 on r1.m_ids = r2.m_ids

给你结果:

   m_ids   | result_1 | result_2
-----------+----------+----------
 {123}     |      111 |       98
 {432,222} |      240 |      215

这看起来与您的预期不同,但根据我对逻辑的理解,它是正确的。如果我有任何误解,请告诉我。


只是为了逻辑说明,一点:

为什么 m_ids 与 {123} returns 111 对于 result_1?

  • 对于 m_ids = {123} 组,我们有两个不同的 p_id
  • 98111都考虑了m_ids长度
  • 相等计数的条件
  • p_id = 111的级别更高,因此被选为result_1