【问题标题】:postgresql: query two tables with same column names and show the result side by side ordered their column names, which occur in both tablespostgresql:查询具有相同列名的两个表并并排显示结果,并排列它们的列名,这两个表都出现
【发布时间】:2022-01-02 09:55:54
【问题描述】:

有两个表(table1table2)具有相同的列名(generationparent),所需的输出将是两个表的所有列的组合。因此 table2 的行应该加入 table1 以便 table2 的行匹配 table1 的行>代列。 table1table2 中的条目的父编号应按升序排列。查询结果的行数应该与table1的行数相等。

给定以下表格
table1

| generation | parent |
|:----------:|:------:|
| 0          | 1      |
| 0          | 2      |
| 0          | 3      |
| 1          | 3      |
| 1          | 2      |
| 1          | 1      |
| 2          | 2      |
| 2          | 1      |
| 2          | 3      |

table2

| generation | parent |
|:----------:|:------:|
| 1          | 3      |
| 1          | 1      |
| 1          | 3      |
| 2          | 1      |
| 2          | 2      |
| 2          | 3      |

以下查询用于创建和填充两个示例表,如上所示:

create table table1(generation integer, parent integer);
insert into table1 (generation, parent) values(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(2,2),(2,1),(2,3);
create table table2(generation integer, parent integer);
insert into table2 (generation, parent) values(1,3),(1,1),(1,3),(2,1),(2,2),(2,3);

想象的查询应该导致以下期望的结果

| table1_generation | table1_parent | table2_generation | table2_parent |
|:-----------------:|:-------------:|:-----------------:|:-------------:|
| 0                 | 1             |                   |               |
| 0                 | 2             |                   |               |
| 0                 | 3             |                   |               |
| 1                 | 1             | 1                 | 1             |
| 1                 | 2             | 1                 | 3             |
| 1                 | 3             | 1                 | 3             |
| 2                 | 1             | 2                 | 1             |
| 2                 | 2             | 2                 | 2             |
| 2                 | 3             | 2                 | 3             |

当前查询如下:

with 
  p as (
    select 
      generation,
      parent 
    from 
      table1
    order by
      generation,
      parent
  ), o as(
    select
      generation,
      parent 
    from 
      table2 
    order by
      generation,
      parent
  )
select
  p.generation as table1_generation,
  p.parent as table1_parent,
  o.generation as table2_generation,
  o.parent as table2_parent
from
  p
left join o on 
  o.generation=p.generation;

这导致以下结果:

| table1_generation | table1_parent | table2_generation | table2_parent |
|:-----------------:|:-------------:|:-----------------:|:-------------:|
| 0                 | 1             |                   |               |
| 0                 | 2             |                   |               |
| 0                 | 3             |                   |               |
| 1                 | 1             | 1                 | 1             |
| 1                 | 1             | 1                 | 3             |
| 1                 | 1             | 1                 | 3             |
| 1                 | 2             | 1                 | 1             |
| 1                 | 2             | 1                 | 3             |
| 1                 | 2             | 1                 | 3             |
| 1                 | 3             | 1                 | 1             |
| 1                 | 3             | 1                 | 3             |
| 1                 | 3             | 1                 | 3             |
| 2                 | 1             | 2                 | 1             |
| 2                 | 1             | 2                 | 2             |
| 2                 | 1             | 2                 | 3             |
| 2                 | 2             | 2                 | 1             |
| 2                 | 2             | 2                 | 2             |
| 2                 | 2             | 2                 | 3             |
| 2                 | 3             | 2                 | 1             |
| 2                 | 3             | 2                 | 2             |
| 2                 | 3             | 2                 | 3             |

This link 得出的结论是,任何连接命令可能都不是这里所必需的......但是联合只附加行......所以对我来说,完全不清楚如何达到预期的结果oO 非常感谢任何帮助。提前致谢!

【问题讨论】:

  • 您能解释一下定义您的输出的规则吗? (edit你的问题并添加)
  • @a_horse_with_no_name 我更新了定义所需输出的规则(问题的开头)。希望你是那个意思。还是您的意思是解释当前输出的规则(这绝对不是预期的结果)?

标签: postgresql join


【解决方案1】:

对这个问题的主要误解源于您提到的 join,这是一个基于笛卡尔积的非常精确的数学定义概念,可以应用于任何两个集合。所以当前的输出是明确的。 但是正如您在标题中所写,您要放置两个表side by side。您可以利用它们具有相同行数(三倍)这一事实。

此选择返回您想要的输出。
我创建了artificial join columnsrow_number() OVER (order by generation, parent) as rnum,并使用三个相加移动了第二个表。希望对您有所帮助:

with 
  p as (
    select 
      row_number() OVER (order by generation, parent) as rnum,
      generation,
      parent 
    from 
      table1
    order by
      generation,
      parent
  ), o as(
    select
      row_number() OVER (order by generation, parent) as rnum,
      generation,
      parent 
    from 
      table2 
    order by
      generation,
      parent
  )
select
  p.generation as table1_generation,
  p.parent as table1_parent,
  o.generation as table2_generation,
  o.parent as table2_parent
from
  p
left join o on 
  o.rnum+3=p.rnum
order by 1,2,3,4;

输出:

table1_generation table1_parent table2_generation table2_parent
0 1 (null) (null)
0 2 (null) (null)
0 3 (null) (null)
1 1 1 1
1 2 1 3
1 3 1 3
2 1 2 1
2 2 2 2
2 3 2 3

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2014-09-28
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多