【问题标题】:SQL strict subset of sets集合的 SQL 严格子集
【发布时间】:2017-01-07 11:05:22
【问题描述】:

我有一个代表图表的表格:

| FROM_ID | TO_ID |
-------------------
| 1       | 9     |
| 1       | 8     |
| 1       | 7     |
| 2       | 7     |
| 2       | 8     |
| 3       | 9     |
| 3       | 7     | 
| 4       | 6     |
| 4       | 8     | 

在实际示例中,有约 500 万行具有约 5k 独特的 FROM 和约 100k 独特的 TO

我想找到所有对 (FROM_ID_X, FROM_ID_Y) s.t.每个 FROM_ID 的 TO_ID 集是另一个 FROM_ID 的严格超集。

所以在这个例子中我会得到: (1,2), (1,3)

为了更清楚地说明这一点: 每行代表图中的一条边。图中的每个节点都属于 A 类或 B 类。一个 A 类节点连接到一个或多个 B 类节点。我想找到 A s.t. 类型的节点对。其中一个指向另一个的严格子集。

使用 postgres fwiw

【问题讨论】:

  • 什么是F?我不跟随。你能重新提出你的问题吗?
  • 更好? F 只是 from 的简写
  • 但如果 TO_ID 的集合是另一个 FROM_ID 的集合的 strict 超集,则有多种选择:简单地添加一个、添加所有等等. 换句话说,结果不是确定性的……
  • (1,3) 来自哪里?您的示例数据中没有这样的行
  • FROM_ID 1 的 TO_ID 集是 {9,8,7},FROM_ID 2 是 {8,7},From id 3 是 {9,7},FROM_ID 4 是 {8 ,6}。因此,2 和 3 都是 1 的子集,但 4 不是

标签: sql postgresql


【解决方案1】:

使用array_agg 将to_id 连接到一个数组中。此后self join 这个cte 使用数组运算符<@ 检查一个数组是否是另一个数组的严格超集。

with concatenated_to as (
select from_id, array_agg(to_id) as arr_to
from t
group by from_id
)
select c1.from_id,c2.from_id 
from concatenated_to c1
join concatenated_to c2 on c1.from_id<>c2.from_id
where c2.arr_to <@ c1.arr_to

Sample Demo

【讨论】:

  • 酷。现在运行它。这是我最初的想法,但担心它在规模上的表现如何。如果它在〜几分钟甚至几小时内运行,那很好。这是一次查询,但想知道是否有更快的方法/数组子集化对性能的影响
【解决方案2】:

这是一种方法:

select t.from_id, t2.from_id
from (select t.*, count(*) over (partition by from_id) as cnt
      from t
     ) t left join
     (select t.*, count(*) over (partition by from_id) as cnt
      from t
     ) t2
     on t.to_id = t2.to_id and t2.cnt = t.cnt
group by t.from_id, t2.from_id
having count(*) = count(t2.from_id);

【讨论】:

  • 获取ERROR: column "t.cnt" must appear in the GROUP BY clause or be used in an aggregate function
  • 我也不确定这是否正确回答了这个问题。为什么连接中的计数应该相等?
  • @marisbest2 。 . .那应该是count(*) = count(t2.from_id)。它只是意味着所有t2 行都匹配。
猜你喜欢
  • 2019-10-06
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-13
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2013-11-26
相关资源
最近更新 更多