如何基于每列为新行创建SQL查询?

如何基于每列为新行创建SQL查询?,sql,group-by,Sql,Group By,我有一个SQL表,如下所示: name, email 1, email 2, email 3 John, john@example.com, info@example.com, hello@example.com Mickey, mickey@disney.com, info@disney.com 我想创建一个查询,为每封电子邮件创建一行 因此,输出将如下所示: John, john@example.com John, info@example.com John, hello@example.

我有一个SQL表,如下所示:

name, email 1, email 2, email 3
John, john@example.com, info@example.com, hello@example.com
Mickey, mickey@disney.com, info@disney.com
我想创建一个查询,为每封电子邮件创建一行

因此,输出将如下所示:

John, john@example.com
John, info@example.com
John, hello@example.com
Mickey, mickey@disney.com
Mickey, info@disney.com

如何实现这一点?

独立于数据库的解决方案使用
union all

select name, email1 as email
from table1
where email1 is not null
union all
select name, email2 as email
from table1
where email2 is not null
union all
select name, email3 as email
from table1
where email3 is not null;

这需要扫描表三次,因此这不是最有效的解决方案。但是,对于小型或中型桌子来说,这是很好的。最好的解决方案取决于您使用的特定数据库——如果性能是一个问题。

独立于数据库的解决方案使用
union all

select name, email1 as email
from table1
where email1 is not null
union all
select name, email2 as email
from table1
where email2 is not null
union all
select name, email3 as email
from table1
where email3 is not null;

这需要扫描表三次,因此这不是最有效的解决方案。但是,对于小型或中型桌子来说,这是很好的。最好的解决方案取决于您正在使用的特定数据库--如果性能是一个问题。

用您正在使用的数据库标记您的问题。一种通用的方法是使用N个联接或一个并集来修复规范化。然后过滤空值。这是group by操作的“反面”。用您正在使用的数据库标记您的问题。一种通用方法是使用N个联接或一个并集来修复规范化。然后过滤空值。这是group by操作的“反面”。可以将筛选器移到union之外以减少SQL布局。@user2864740。您需要使用CTE或子查询。@GordonLinoff谢谢!所以基本上,说“union all”基本上是基于参数生成一个虚拟行是正确的吗?@SnowboardBruin
union all
将两个或多个子查询的结果合并到一个结果集中,假设它们具有相同的列数,并且类型与每个对应的列兼容。可以将筛选器移到union之外以减少SQL布局。@user2864740。您需要使用CTE或子查询。@GordonLinoff谢谢!所以基本上,说“union all”基本上是基于参数生成一个虚拟行是正确的吗?@SnowboardBruin
union all
将两个或多个子查询的结果合并到一个结果集中,假设它们具有相同的列数,并且每个对应列的类型都兼容。