Postgres RIGHT JOIN 与自定义数组

Jon*_*Jon 8 postgresql join

我正在使用 Postgres 9.1 并希望得到一些没有数据的空白结果。我的查询如下所示:

SELECT institution_id FROM ... WHERE institution_id IN (1, 3, 4, 5, 7, 9)
Run Code Online (Sandbox Code Playgroud)

... 对这个问题并不重要,重要的是它返回一个包含数组中机构 ID 的结果 (1, 3, 4, 5, 7, 9) 并且它包括那些没有数据的机构。以下是当前输出的示例:

days    treatments    institution_id
266    6996    4
265    5310    1
267    3361    5
260    2809    3
264    5249    7
Run Code Online (Sandbox Code Playgroud)

我想要的输出示例是:

days    treatments    institution_id
266    6996    4
265    5310    1
267    3361    5
260    2809    3
264    5249    7
               9
Run Code Online (Sandbox Code Playgroud)

我知道我可以通过使用以下查询来实现这一点:

SELECT *
FROM (
       SELECT institution_id
       FROM ... 
       WHERE institution_id IN (1, 3, 4, 5, 7, 9)
     )
RIGHT JOIN generate_series(1,9) ON generate_series = institution_id
WHERE generate_series IN (1, 3, 4, 5, 7, 9)
Run Code Online (Sandbox Code Playgroud)

但是,这是额外的工作,因为 generate_series(1,9) 创建了我不感兴趣的机构 ID,它要求我先验地知道最大机构 ID,并且它引入了一个不必要的 WHERE 子句。理想情况下,我想要如下查询:

SELECT *
FROM (
      SELECT institution_id
      FROM ...
      WHERE institution_id IN (1, 3, 4, 5, 7, 9)
     )
RIGHT JOIN (1, 3, 4, 5, 7, 9) ON generate_series = institution_id
Run Code Online (Sandbox Code Playgroud)

哪里(1, 3, 4, 5, 7, 9)只是一个 Postgres 将用于 JOIN 命令的数组。我也已经尝试过了[1, 3, 4, 5, 7, 9]{1, 3, 4, 5, 7, 9}都无济于事。

有任何想法吗?

Dan*_*ité 14

您可以直接使用值列表执行 OUTER JOIN,如下所示:

SELECT v.id,tablename.* FROM tablename RIGHT JOIN (values (1),(3),...,(9)) as v(id)
  ON (tablename.field=v.id)
Run Code Online (Sandbox Code Playgroud)


Erw*_*ter 5

基于ID数组unnest(),您可以使用:

SELECT i.institution_id, t.*
FROM   unnest('{1, 3, 4, 5, 7, 9}'::int[]) institution_id
LEFT   JOIN tbl t USING (institution_id);
Run Code Online (Sandbox Code Playgroud)

使用LEFT JOIN效果相同。
要不就:

SELECT *
FROM   unnest('{1, 3, 4, 5, 7, 9}'::int[]) institution_id
LEFT   JOIN tbl t USING (institution_id);
Run Code Online (Sandbox Code Playgroud)

连接条件中的子句USING仅将单个实例添加institution_id到输出列。SELECT *可能正是您想要的。或不。如果的所有其他列都tbl可以NULLinstitution_id是唯一的非空列),那么您现在无法区分缺失行和一行NULL值之间的区别。

还要保留输入数组中元素的顺序:

SELECT *
FROM   unnest('{7, 3, 4, 1, 5, 9}'::int[])  WITH ORDINALITY AS i(institution_id, ord)
LEFT   JOIN tbl t USING (institution_id);
ORDER  BY i.ord;
Run Code Online (Sandbox Code Playgroud)

看: