遍历 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
我必须执行以下操作:
通过以下算法提取p_id
- 对于具有相同
m_ids
的每一行
- 每组:
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_id
和 level=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
值
98
和111
都考虑了m_ids
长度 相等计数的条件
p_id = 111
的级别更高,因此被选为result_1
我有以下数据:
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
我必须执行以下操作:
通过以下算法提取
p_id
- 对于具有相同
m_ids
的每一行
- 每组:
2.I。按p_id
对记录进行分组 2.I我。按level
排序 desc 记录 2.I二. Selectp_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_id
和 level=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
值 98
和111
都考虑了m_ids
长度 相等计数的条件
p_id = 111
的级别更高,因此被选为result_1