SQL查找表并为每个字段创建一条记录

时间:2014-07-18 13:23:26

标签: sql sql-server database

我的数据库中有三个表。

表一实际上包含两个字段:

|Datetime| |Set|

表2是一个查找表,它将集合的多个部分与设定的数字相匹配:

|Set| |Part1| |Part2| |Part3| |Part4|

我希望表3为特定日期时间的集合中的每个部分创建记录:

|Datetime| |Part|

填充表格如下所示:

|12:00:00| |Set1_Part1|
|12:00:00| |Set1_Part2|
|12:00:00| |Set1_Part3|
|12:00:00| |Set1_Part4|
|12:02:30| |Set2_Part1|
|12:02:30| |Set2_Part2|
|12:02:30| |Set2_Part3|
|12:02:30| |Set2_Part4|

因此,我在表1中获得了关于集合和日期时间的一些信息,然后表3需要有效地将其外推到集合中每个部分的日期时间/部分对。

有什么想法吗? (这适用于SQL Server)

3 个答案:

答案 0 :(得分:1)

也许就像......

Insert Into table3 (
Select datetime, set + '_' + Part1
FROM table1
INNER JOIN table2 
  on T1.Set=T2.Set 
  and Part1 is not null
UNION
Select datetime, set + '_' + Part2
FROM table1
INNER JOIN table2 
  on T1.Set=T2.Set
  and Part2 is not null
UNION
Select datetime, set + '_' + Part3
FROM table1
INNER JOIN table2 
  on T1.Set=T2.Set
 and Part3 is not null
UNION
Select datetime, set + '_' + Part4
FROM table1
INNER JOIN table2 
  on T1.Set=T2.Set
 and Part4 is not null
UNION
Select datetime, set + '_' + Part5
FROM table1
INNER JOIN table2 
  on T1.Set=T2.Set
 and Part5 is not null

答案 1 :(得分:1)

在SQL Server中执行此操作的“规范”方法是使用union all

select t1.datetime, t2.part
from ((select set, Part1 as part from table2) union all
      (select set, Part2 from table2) union all
      (select set, Part3 from table2) union all
      (select set, Part4 from table2)
     ) t join
     table1 t1
     on t1.set = t.set;

如果要将其存储在另一个表中,可以使用into table3子句。请注意,setdatetime是保留字,因此如果这些是列的真实名称,则它们应该是方括号。

还有其他方法可以做到这一点,包括unpivot(非常特定于SQL Server)和使用条件进行交叉连接。但是,如果可以的话,最好将table2标准化。列将是:

  • 部分
  • 部分号码

所以一行会变成四行。

答案 2 :(得分:0)

这是规范化如此重要的另一个原因。如果您没有将所有零件号列为列,这不会成为问题。我们可以在这里利用CROSS APPLY进行简短的工作。

create table #Something
(
    SetName varchar(10)
    , Part1 varchar(10)
    , Part2 varchar(10)
    , Part3 varchar(10)
    , Part4 varchar(10)
    , Part5 varchar(10)
)

insert #Something
select 'Set 1', 'Part 1', 'Part 2', 'Part 3', 'Part 4', null union all
select 'Set 2', 'Part 1', 'Part 2', 'Part 3', 'Part 4', 'Part 5' 

select s.SetName, d.Part
from #Something s
cross apply (VALUES (Part1), (Part2), (Part3), (Part4), (Part5)) d (Part)
where d.Part is not null