【问题标题】:SQL query from flat file来自平面文件的 SQL 查询
【发布时间】:2010-01-19 20:23:56
【问题描述】:

我有一张桌子,例如:

John email1 email2 email3 ...and so on

我需要将数据集转换成这种格式:

John email1
John email2
John email3

如果这样更容易,它可以导出到 Excel 并重新导入。谢谢...

【问题讨论】:

  • John 的电子邮件地址与 Bob 的电子邮件地址有什么区别?
  • 另外,这是一个平面文件,还是一个 SQL 数据库?是 MSSQL、MySQL、PostgreSQL 等吗?
  • @Jordan:你确定新格式是 Richard 想要的吗?与他最初描述的情况相比,这是一个根本性的变化。
  • @Richard:如果乔丹的编辑是你的意思,你应该插话......
  • @Mark - 是的,这就是 OP 想要的……如果您单击已编辑并查看您可以看到的原始问题的来源。

标签: sql select


【解决方案1】:

假设 Name、Email1、Email2、Email3 是列名:

   Select Name, Email1
    From YourTable
    Where Email1 <> ''
    Union
    Select Name, Email2
    From YourTable
    Where Email2 <> ''
    Union
    Select Name, Email3
    From YourTable
    Where Email3 <> ''

【讨论】:

  • 完成后确保按名称排序,以便将所有同名的电子邮件地址放在一起。
  • 注意:有了这个,你必须有最长行的 IE 的联合数,如果你有 7 个电子邮件地址给一个人,你需要有 7 个联合。根据需要扩展。
  • 谢谢 Lynette,这是很棒的信息。我想我喜欢 unpivot,但这只是个人喜好。
【解决方案2】:

你是什么意思修复?你可以这样做:

SELECT name+' '+email1 as email1,
       name+' '+email2 as email2, 
       name+' '+email3 as email3, 
       name+' '+email3 as email3, 
       ...
FROM table

上面是在我看到格式化之前写的......我相信这就是你想要的——只在 mssqlserver 上测试过

declare @t table
(
  name varchar(max),
  email1 varchar(max),
  email2 varchar(max),
  email3 varchar(max),
  email4 varchar(max)
)

insert into @t 
 values ('name1a','email1a','email2a','email3a','email4a')
insert into @t  
 values ('name2b','email1b','email2b','email3b','email4b')

 select * from @t

SELECT name, email 
FROM
(
SELECT name, email1, email2, email3, email4
FROM @t) p
UNPIVOT
   (email FOR emails IN 
      (email1, email2, email3, email4)
)AS unpvt

【讨论】:

  • UNPIVOT 正是我们所需要的。下面的帖子有一个联合作为答案,它同样有效,只是 UNPIVOT 更容易(对我来说)阅读和理解。
  • @Richard - 如果这是您喜欢的答案,请单击复选框(并投票),问题将关闭。欢迎使用 StackOverflow。
【解决方案3】:

我认为没有理由“退出”到 XLS 或其他东西,然后重新导入。

您可以通过以下方式解决此问题

1)(仅在认为值得的情况下,取决于数据库大小、行数等),可能会在表上删除一些索引。

2) 运行 INSERT 查询以添加新行,即这些由 Name 和“Emailn”列(以及其他所需的列或所需的默认值)组成

3) 一旦所有“Emailn”列都发送完毕,更改表架构以删除这些列。

4) 重新构建之前删除的索引和/或重新打包其他索引。

具体来说,对于#2,查询看起来像

INSERT INTO MyTable 
   (Name, Email1, SomeOtherColumn, YetOtherColumn)
   SELECT Name, Email2, someColumn, "ABC"
   FROM MyTable
   WHERE Email2 IS NOT NULL

当然,您可以为 Email1 之外的每个“Emailn”列执行此操作。等等……

只有在表格很大等情况下可能会遇到困难,但由于您正在考虑使用 Excel,因此可能并非如此。

【讨论】:

  • 感谢 mjv,您是正确的,因为使用 Excel 导出/导入只是不需要采取的两个额外步骤。我正在获取这些数据并在它当前所在的表中添加更多行。有超过 11000 个名称,可能有 8000 个有多个电子邮件。完成此操作后,您的第 3 步正是计划的内容。谢谢...
【解决方案4】:

彻底检修(我最初的答案是基于问题的短暂错误版本)。

如果“平面文件”指的是文本文件,那么用于转换的简单(非 SQL)版本将使用 awk 与以下内容:

awk "{ for (i = 2; i <= NF; i++ ) { print $1, $i }}" < original.txt

【讨论】:

  • 这是否真的实现了他想要的:IE 将每个电子邮件地址放在自己的行中?
  • 我不确定。理查德的原始帖子完全显示在一行中。将其更改为每行一个的是另一个人,这当然更有意义,但不是最初的问题。
  • @Mark 我认为这是最初的问题,Lynette 的格式很糟糕
  • 我想我们最终会知道他什么时候回来检查。他现在有很多答案可供选择。有点好笑。我们都在疯狂地回答可能不是问题的问题。
  • 感谢您的回复,但它是一张表格,而且都在一行中 - 姓名、电子邮件 1、电子邮件 2、电子邮件 3 等等。如果我不清楚,我很抱歉......
猜你喜欢
  • 1970-01-01
  • 2011-01-17
  • 1970-01-01
  • 2015-08-21
  • 2016-01-18
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 1970-01-01
相关资源
最近更新 更多