【问题标题】:Self joining a table n times自加入一张桌子 n 次
【发布时间】:2017-10-28 14:55:14
【问题描述】:

我正在尝试找到一个生物学“找到一组给定生物的核心基因组”的问题。本质上,给定一个生物列表,找出它们共有的所有基因。为了抽象出生物学,您可以考虑在一组人中找到最喜欢的所有颜色(一个人可以有多种喜欢的颜色)。

数据库表如下所示:

name | fav_colour
john | red
john | blue
john | green
jason | red
jason | blue
matt | red
matt | teal

用户可以指定一组名称,例如 [john, jason] 以获取 [red, blue],或 [john] 以获取 [red, blue, green],或 [john, jason, matt] 以获取 [红色]。

我正在尝试通过执行 n 次自连接来解决这个问题,其中 n 是提供的名称数。

我有什么方法可以对提供的任意数量的名称进行 n 次表的自连接来解决这个问题?我试图通过 Postgres 函数寻找一种方法来解决这个问题,但是无法计算出 n 个自连接部分...任何帮助或指向正确方向的指针将不胜感激。

不,很遗憾,我无法更改架构以更轻松地执行这些类型的查询。

【问题讨论】:

  • 连接方法对我来说不是什么......我对此的第一个想法是使用聚合,使用 group by 和 count(*) 计算每个基因有多少生物,然后使用计数=生物的数量。想到的另一个想法是将每个有机体的查询串在一起,并使用 INTERSECT 来获取公共元素。
  • 究竟如何用户“指定一组名称”?我们可以假设它们在一个包含一列名称的表中吗?
  • @philipxy 我希望有一个存储过程,它接受一个被解析和计数的值数组。数组中的项目数为 n,这将是所需的自连接数。
  • 请将其编辑到您的问题中。还能怎么回答?还有更多关于你试图通过“自我加入”来捕捉的信息。例如,另一个评论的“即名称列在 n 个表中是唯一的”。在具有重命名的关系代数中,如果表行相同,它们不会是自连接,除非它们是常量因此微不足道。 (自我加入是不相关的。)(请参阅我编辑的答案。)尝试为您的想法写一个表达式和/或示例。 PS 对于所有数组,循环和计数你显然没有相关性地思考。
  • 您想要“关系除法”,将名称颜色表除以名称表。

标签: sql postgresql join self-join sql-function


【解决方案1】:

我认为您不需要为此自行加入。您可以使用聚合和 HAVING 子句:

with t(name, fav_colour) as (
      values ('john', 'red'),
             ('john', 'blue'),
             ('john', 'green'),
             ('jason', 'red'),
             ('jason', 'blue'),
             ('matt', 'red'),
             ('matt', 'teal')
     )
select fav_colour
from t
where name in ('john', 'jason')
group by fav_colour
having count(*) = 2;

值“2”是列表中名称的数量。更改IN 列表和计数是您需要的唯一更改。

【讨论】:

  • 如果还有其他列,这将如何工作?例如,根据 fav_colour 列中的值找到最喜欢的颜色,但还返回年龄(在 John、Jason 示例的情况下为两个不同的年龄)(如果我们也可以返回一个特定工作人员的年龄,即返回一个基因 ID定义的物种)。对于我的数据,共同基因是根据描述栏找到的,但是不同物种的基因有不同的ID,可以进一步查询。
  • @player87 。 . .如果您还有其他问题,请作为another 问题提出。这个问题具体是关于两列的,改变问题可能会使这个答案无效并吸引反对票。但是,如果您只想要匹配行中的年龄,您可以使用array_agg()
  • 实际上 array_agg() 适用于我想做的事情。但是,只是对原始问题的跟进,实际上是否可以在给定条件下进行 n 次自连接(即名称列在 n 个表中是唯一的)?
  • @player87 - 当然,从形式上讲,您不能进行未知数量的自加入。在您可能需要的情况下,解决方案是使用标准或自定义聚合函数或递归查询。请参阅this answer 以查看此类自加入 的示例。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多