如何从PostgreSQL的单行数据库表中获取多行?

时间:2018-10-22 10:19:52

标签: sql postgresql union unpivot

我有一个PostgreSQL数据库表名称Intime

| Name  |  Intime1 |      Intime2     |   Intime3 |      Intime4     |  Intime5 |      Intime6     |
|-------|----------|------------------|-----------|------------------|----------|------------------|
| Zakir |          |    02/01/18:9.00 |           |    04/01/18:9.07 |          |    06/01/18:9.05 |

我想要这张桌子:

| Name  |     Intime    |
|-------|---------------|
| Zakir | 02/01/18:9.00 |
| Zakir | 04/01/18:9.07 |
| Zakir | 06/01/18:9.05 |

现在PostgreSQL中的查询是什么?

2 个答案:

答案 0 :(得分:1)

使用UNION:

select name, intime1 as intime
from intime
union all
select name, intime2
from intime
union all
select name, intime3
from intime
union all
select name, intime4
from intime
union all
select name, intime5
from intime
union all
select name, intime6
from intime

另一种特定于Postgres的解决方案是在列的数组上使用unnest

select i.name, t.intime
from intime as i
  cross join unnest(array[intime1,intime2,intime3,intime4,intime5,intime6]) as t(intime);

如果您还想知道每一行属于哪一列,可以使用with ordinality

select i.name, t.intime, t.nr
from intime as i
  cross join unnest(array[intime1,intime2,intime3,intime4,intime5,intime6]) with ordinality as t(intime,nr);

在线示例:https://rextester.com/CDHVI81806

答案 1 :(得分:1)

使用横向连接:

select t.name, v.intime
from t cross join lateral
      (values (intime1), (intime2), (intime3), (intime4), (intime5), (intime6)
      ) v(intime);

横向连接是ANSI / ISO标准语法,功能可能非常强大。取消数据透视只能用它们来完成。