SQL - 在同一个表中复制数据

时间:2014-01-02 22:52:45

标签: sql sql-server

我对SQL Server并不是那么出色,但我正在尝试做一些幕后工作来创建我们的EMR系统缺乏的一些功能 - 在病人之间复制表格(及其所有数据)。

在SQL Server 2008 R2中,我有三个表来处理已填写的表格:

**Table 1**
encounter_id  patient_id  date        time          etc  etc  etc  etc
1234          112233      2014-01-02  14:25:01:00   a    b    c    d

**Table 2**
encounter_id  page  recorded_on  recorded_by  etc   etc
1234          1     2014-01-02   134          asdf  asdf
1234          2     2014-01-02   134          jkl;  jkl;

**Table 3**
encounter_id  page  keyname  keyvalue
1234          1     key1     aaa
1234          1     key2     bbb
1234          1     key3     ccc
1234          1     key4     ddd
1234          2     key5     eee
1234          2     key6     fff
1234          2     key7     ggg

正如您所看到的,它们都与encounter_id一起匹配,meet_id链接到patient_id(在第一个表中)。

我正在努力做的是将这三个表中的所有行复制到特定的encounter_id中,然后将它们复制到它们来自同一个表中,但是对于patient_id,我会使用不同的(系统生成的)encounter_id指定。实质上,将表格从一个病人复制到另一个病人。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

我总是喜欢在[tempdb]中创建示例表,以便语法正确。我创建了表[t1],[t2]和[t3]。有主键和外键。

如果你有一个完善的架构,ERD(实体关系图)http://en.wikipedia.org/wiki/Entity-relationship_diagram,这些关系应该就位。

-- Playing around
use tempdb
go


--
-- Table 1
--

-- Remove if it exists
if object_id('t1') > 0
drop table t1
go

-- Create the first table
create table t1
(
encounter_id int,
patient_id int, 
the_date date,
the_time time,
constraint pk_t1 primary key (encounter_id)
);
go

-- Add one row
insert into t1 values (1234, 112233, '2014-01-02', '14:25:01:00');
go

-- Show the data
select * from t1
go


--
-- Table 2
--

-- Remove if it exists
if object_id('t2') > 0
drop table t2
go

-- Create the second table
create table t2
(
encounter_id int,
the_page int,
recorded_on date,
recorded_by int,
constraint pk_t2 primary key (encounter_id, the_page)
);
go

-- Add two rows
insert into t2 values 
(1234, 1, '2014-01-02', 134),
(1234, 2, '2014-01-02', 134);    
go  

-- Show the data
select * from t2
go

--
-- Table 3
--

-- Remove if it exists
if object_id('t3') > 0
drop table t3
go

-- Create the third table
create table t3
(
encounter_id int,
the_page int,
key_name1 varchar(16),
key_value1 varchar(16),
constraint pk_t3 primary key (encounter_id, the_page, key_name1)
);
go

-- Add seven rows
insert into t3 values 
(1234, 1, 'key1', 'aaa'),
(1234, 1, 'key2', 'bbb'),
(1234, 1, 'key3', 'ccc'),
(1234, 1, 'key4', 'ddd'),
(1234, 2, 'key5', 'eee'),
(1234, 2, 'key6', 'fff'),
(1234, 2, 'key7', 'ggg');
go

-- Show the data
select * from t3
go

--
-- Foreign Keys
--

alter table t2 with check
add constraint fk_t2 foreign key (encounter_id)
references t1 (encounter_id);

alter table t3 with check
add constraint fk_t3 foreign key (encounter_id, the_page)
references t2 (encounter_id, the_page);

这是一个有趣的部分,一个复制数据的存储过程。

--
-- Procedure to duplicate one record
--

-- Remove if it exists
if object_id('usp_Duplicate_Data') > 0
drop procedure t1
go

-- Create the procedure
create procedure usp_Duplicate_Data @OldId int, @NewId int
as
begin

  -- Duplicate table 1's data
  insert into t1 
  select 
    @NewId,
    patient_id, 
    the_date,
    the_time
  from t1
  where encounter_id = @OldId;

  -- Duplicate table 2's data
  insert into t2 
  select 
    @NewId,
    the_page, 
    recorded_on,
    recorded_by
  from t2
  where encounter_id = @OldId;

  -- Duplicate table 3's data
  insert into t3 
  select 
    @NewId,
    the_page, 
    key_name1,
    key_value1
  from t3
  where encounter_id = @OldId;

end

最后但并非最不重要的是,我们必须调用存储过程以确保它有效。

-- Sample call
exec usp_Duplicate_Data 1234, 7777

总之,我没有添加任何错误检查或计算一系列Id。我留下这些任务供你学习。

enter image description here

答案 1 :(得分:1)

declare @oldEncounterID int
set @oldEncounterID = 1234

declare @newEncounterID int
set @newEncounterID = 2345

insert into table1(encounter_id, patient_id, date, time, etc)
select newEncounterID, patient_id, date, time, etc
from table1 where encounter_id = oldEncounterID

等等......这种方法的问题你必须知道所有列的优点,如果它们发生了变化,你可以相应地更改列

另一种方法:

declare @oldEncounterID int
set @oldEncounterID = 1234

declare @newEncounterID int
set @newEncounterID = 2345
select * into #table1 from table1 where encounter_id = oldEncounterID
update #table1 set encounter_id = newEncounterID
insert into table1 select * from #table1

依旧......如果有一个标识列,那么第二种方法可能需要稍微调整一下,那么你必须将identity_insert设置为on

答案 2 :(得分:1)

伪代码,未经测试:

DECLARE @patient_id INT, @date datetime, @time ??
SET @patient_id = 112244 --your patient id

INSERT INTO [**Table 1**] (patient_id, date, time, etc, etc, etc, etc)
VALUES (@patient_id, @date, @time, 'a', 'b', 'c', 'd')

DECLARE @encounter_id int
SET @encounter_id = SCOPE_IDENTITY  -- or select @encounter_id = encounter_id from [**Table 1**] where patientId = @patient_id

INSERT INTO [**Table 2**] (encounter_id, page, recorded_on, recorded_by, etc, etc2)
SELECT @encounter_id, page, recorded_on, recorded_by, etc, etc2 
FROM [**Table 2**]
WHERE encounter_id = 1234

INSERT INTO [**Table 3**] (encounter_id, page, keyname, keyvalue)
SELECT @encounter_id, page, keyname, keyvalue
FROM [**Table 3**]
WHERE encounter_id = 1234

答案 3 :(得分:1)

作为一个小例子,here (link)

解决方案可能是不必要的复杂但它提供了很多其他有用的东西,我只是想测试如何动态构建它。该脚本会打印出命令,使得删除TSQL变得相对容易,只需按照您的意愿生成纯SQL即可。

它的作用是,它需要一个encounter_id,它将用于动态获取列(假设encounter_id是TABLE_1的PK)在TABLE_1中插入新记录,存储inserted.encounter_id值,并使用该值来获取和复制TABLE_2和TABLE_3中的匹配行。

基本上,只要结构正确(TABLE_1 PK是meet_id是一种标识类型),您应该能够只更改脚本中引用的表名,它应该直接工作,无论哪种类型的列(你的特定桌子有多少个。

剧本的牛肉是:

/* Script begins here */
DECLARE @ENCOUNTER_ID INT, @NEWID INT, @SQL VARCHAR(MAX), @COLUMNS VARCHAR(MAX)
IF OBJECT_ID('tempdb..##NEW_ID') IS NOT NULL
    DROP TABLE ##NEW_ID
CREATE TABLE ##NEW_ID (ID INT)

/* !!! SET YOUR DESIRED encounter_id RECORDS TO BE COPIED, HERE !!! */
  SET @ENCOUNTER_ID = 1234

IF EXISTS (SELECT TOP 1 1 FROM TABLE_1 WHERE encounter_id = @ENCOUNTER_ID)
BEGIN
    SELECT @COLUMNS = COALESCE(@COLUMNS+', ', 'SELECT ')+name
    FROM sys.columns WHERE OBJECT_NAME(object_id) = 'TABLE_1' AND name <> 'encounter_id'

    SET @COLUMNS = 'INSERT INTO TABLE_1 OUTPUT inserted.encounter_id INTO ##NEW_ID '+@COLUMNS+' FROM TABLE_1 WHERE encounter_id = '+CAST(@ENCOUNTER_ID AS VARCHAR(25))

    EXEC(@COLUMNS)
    PRINT(@COLUMNS)

    SELECT TOP 1 @NEWID = ID, @COLUMNS = NULL FROM ##NEW_ID

    SELECT @COLUMNS = COALESCE(@COLUMNS+', ', '')+name
    FROM sys.columns WHERE OBJECT_NAME(object_id) = 'TABLE_2'
    SET @COLUMNS = 'INSERT INTO TABLE_2 ('+@COLUMNS+') SELECT '+REPLACE(@COLUMNS,'encounter_id',''+CAST(@NEWID AS VARCHAR(25))+'')
        +' FROM TABLE_2 WHERE encounter_id = '+CAST(@ENCOUNTER_ID AS VARCHAR(25))

    EXEC(@COLUMNS)
    PRINT(@COLUMNS)

    SET @COLUMNS = NULL

    SELECT @COLUMNS = COALESCE(@COLUMNS+', ', '')+name
    FROM sys.columns WHERE OBJECT_NAME(object_id) = 'TABLE_3'
    SET @COLUMNS = 'INSERT INTO TABLE_3 ('+@COLUMNS+') SELECT '+REPLACE(@COLUMNS,'encounter_id',''+CAST(@NEWID AS VARCHAR(25))+'')
        +' FROM TABLE_3 WHERE encounter_id = '+CAST(@ENCOUNTER_ID AS VARCHAR(25))

    EXEC(@COLUMNS)
    PRINT(@COLUMNS)

    IF OBJECT_ID('tempdb..##NEW_ID') IS NOT NULL
        DROP TABLE ##NEW_ID
END