2011-04-14 21 views
1

我还在学习SQL。我有关于更新表的问题。我如何根据其他表更新我的表?请看下面的例子:SQL Server初学者:如何从另一个表更新表数据?

create table batch_info (
    batch_key int identity(1, 1) not null primary key, 
    batch_num int not null, 
    batch_name varchar(50) null, 
    batch_start datetime null, 
    batch_end datetime null, 
    table_name varchar(50) null, 
    insert_rows int null 
) 
go 

insert into batch_info (batch_num, batch_name, batch_start) 
    values ('32', 'Batch_to_insert_rows', '20110414') 
go 

select * from batch_info 

create table ref_table (
    bat_num int not null, 
    bat_end_date datetime null, 
    bat_table_name varchar(50) null, 
    bat_ins_rows int null, 
) 
go 

insert into ref_table 
    values ('32','20110414 02:12:00.000','Table1','10'), 
      ('32','20110414 02:12:00.000','Table2','33'), 
      ('32','20110414 02:12:00.000','Table3','12') 

select * from ref_table 

--How can I update batch_info table to get this info? 
select 
bi.batch_key, 
bi.batch_num, 
bi.batch_name, 
bi.batch_start, 
rt.bat_end_date, 
rt.bat_table_name, 
rt.bat_ins_rows 
from batch_info as bi 
inner join ref_table as rt on bi.batch_num = rt.bat_num 

编辑:一批重点是代孕所以它应该是渐进的,而不是(1,1,1)在我的连接查询。

回答

3

假设batch_num和bat_end_date的组合是唯一的,那么这应该做的伎俩:

update batch_info 
set  batch_end = rt.bat_end_date, 
     table_name = rt.bat_table_name, 
     insert_rows = rt.bat_ins_rows 
from batch_info bi 
     inner join ref_table rt on rt.bat_num = bi.batch_num 
     inner join 
     (
      select bat_num, 
        MIN(bat_end_date) as min_bat_end_date 
      from ref_table 
     ) oldest on oldest.bat_num = rt.bat_num 
        and oldest.min_bat_end_date = rt.bat_end_date 
where bi.batch_end is null 

insert into batch_info 
(batch_num, batch_name, batch_start, batch_end, table_name, insert_rows) 
select bi.batch_num, 
     bi.batch_name, 
     bi.batch_start, 
     rt.bat_end_date, 
     rt.bat_table_name, 
     rt.bat_ins_rows 
from batch_info bi 
     inner join ref_table rt on rt.bat_num = bi.batch_num 
where not exists 
     (
      select * 
      from  batch_info e 
      where e.batch_num = bi.batch_num 
        and e.batch_end = rt.bat_end_date 
     ) 

如果值的另一组合建立的独特性,则这些可以在第一个查询添加到oldest,和e在第二。

我同意@Jim,这应该被分成两个表。执行此操作的难度是此设计将产生的困难的预兆。您试图将两种不同的东西(批次和批次运行)放到一张表中,这绝不是一个好主意。

+0

@Jeffrey +1为你回答没有光标(ick)的问题,就像我建议的那样。但正如我们双方都同意的那样,它应该是两张桌子。 – Jim 2011-04-14 21:32:14

+0

谢谢。第一条语句会生成一个错误:消息8120,级别16,状态1,行9 列'ref_table.bat_num'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。 – jrara 2011-04-15 04:16:31

+0

而插入语句似乎没有插入任何东西在这个例子中。 – jrara 2011-04-15 04:20:39

0
insert into batch_info 
SELECT batch_num, batch_name, batch_start, 
bat_end, bat_table_name, bat_ins_rows 
FROM batch_info inner join ref_table 
on batch_info.batch_num = ref_table.bat_num 

delete from batch_info 
where batch_end is null 

编辑:INSERT正在生成的所有匹配行&重新插入。新的身份值将被添加到这些。现有行(其他字段为空)用于INSERT语句&,后面使用第二个语句删除。

0

我打算告诉你Merge Statement,但我不认为这可以做到这一点。我想你会被卡住,使用Cursor

有了这个说法并不知道你现有的要求,它真的应该是两个表。把所有东西都放到一张桌子里,就是使桌子设计非规范化。

+0

我没有使用操作数据库。这个batch_info表是数据仓库中的一个日志表,所以我认为它可以非规范化这个。 – jrara 2011-04-15 04:26:27

0

使batch_info.batch_key字段自动增量。

create table batch_info (
batch_key int identity(1, 1) not null primary key, -- <<- make autoincrement. 
... 
相关问题