繁体   English   中英

如何外连接两个表(主表和多对一子表)以仅从第二个表中获取一项?

[英]How to outer-join two tables (main and many-to-one sub-table) to get only ONE item from second table?

我有两个类似这样的表:

主表:id(int)、title(varchar)等 子表:main_table_id(主表的外键)、tag(varchar)等

对于主表中的给定行,可以有零个或多个子表行。

我想做一个查询,它将返回主表的每一行,主表的列,以及子表的单行(无关紧要)中的列,如果有的话,否则这些列中的 NULL 。

当然,如果我只是做一个基本的 LEFT OUTER JOIN,那么我当然会让主表重复多次,子表中的每个匹配一个。

我确信我在使用 LEFT OUTER JOIN 和某种技巧之前已经看到了这一点,它强制从子表中只选择一行,而不是全部 - 也许选择最小或最大 OID。 然而,一个多小时的谷歌搜索并没有产生任何解决方案。

有人在他们的工具带中有这个技巧吗?

如果您使用的是 SQL 服务器,则可以使用 TOP 子句。 如果它不是 SQL 服务器,您必须查看该数据库是否提供等效的东西(其中许多提供)。 像这样的东西...

Select * from Main m
left outer join 
(select top 1 * from subtable s
  where s.main_table_id = m.id) q
on q.main_table_id = m.id;

注意:这是向您展示总体思路。 我没有机会运行它,因此可能需要进行一些更改,但概念就在那里。

我最喜欢查理的回答,但我不确定 Postges 是否有 TOP/LIMIT function,所以这是一个不需要的替代解决方案(但假设 sub_table 有一个名为“id”的主键):

SELECT * 
FROM main_table m LEFT OUTER JOIN sub_table s 
ON s.main_table_id = m.id
WHERE s.id IS NULL OR s.id IN ( 
  SELECT MAX(id) FROM sub_table GROUP BY main_table_id
)

Postgres 中的有趣方法(根本不是 schooll):

SELECT * 
 FROM main_table m left join (
   select (max(s::character varying)::subtable).* from subtable s group by main_table_id 
 ) s ON s.main_table_id = m.id

解释:
您将 select 完整记录为一个字段:

select s from subtable s

您将其转换为字符以能够使用最大聚合(或最小...)

 select max(s::character varying) from subtable s group by main_table_id

您仅通过 main_table_id 获得一行,其中包含代表您的记录的 varchar,因此我们必须再次在“subtable”中转换并分解它 -> (myvarchar::subtable)。*

select (max(s::character varying)::subtable).* from subtable s group by main_table_id 

您只需一行 main_table_id 即可获得表格子表

如果您只是检查第二个表中的某些内容与第一个表中的项目一起使用,则可以使用带有 group by 子句和聚合的外连接:

select t1.[name], count(t1.[name]) as t2count
   from table1 t1
   left outer join table2 t2 on t1.fk = t2.pk
group by t1.[name]

然后,t2count 为 0 的任何内容都将是 table2 中没有任何内容的内容

编辑:实际上,我不记得 t2count 是否会有 null 或 0 ......它应该是这些值之一。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM