这是我的第一个问题,所以不知道哪里可能出错。 这是我的场景: 我有两个表:tblA和tblB。首先填充tblA中的某些数据然后填充tblB中的相同数据的过程。现在由于过程查询中的某些小故障,某些列的某些值未插入到tblB中,而是插入到tblA中。我现在想用tblA中的记录更新tblB。我找不到相应的更新记录。 为了简化任务,我已经准备好了使用查询的样本
--DROP TABLE #tblA
--DROP TABLE #tblB
--TRUNCATE TABLE #tblA
--TRUNCATE TABLE #tblB
CREATE TABLE #tblA (col1 char(2), col2 char(2), col3 int, col4 char)
CREATE TABLE #tblB (ID char(2),col1 char(2), col2 char(2), col3 int, col4 char)
INSERT INTO #tblA VALUES ('A','B',1,'C')
INSERT INTO #tblA VALUES ('A1','B',2,'C')
INSERT INTO #tblA VALUES ('A1','B',3,'C')
INSERT INTO #tblB VALUES ('I1','A','B',NULL,'C') -- Here we can see that values could not be inserted in col3
INSERT INTO #tblB VALUES ('I2','A1','B',NULL,'C')
INSERT INTO #tblB VALUES ('I3','A1','B',3,'C')
到目前为止我尝试了什么(不包括我尝试的其他查询,这给了我最接近的结果) (我甚至尝过了评论部分)
--UPDATE B
--SET B.col3=A.col3
SELECT DISTINCT A.*, B.*
FROM #tblA A
INNER JOIN #tblB B
ON 1=1
AND A.col1=B.col1
AND A.col2 = B.col2
AND A.col4 = B.col4
--AND (A.col3<>B.col3)
AND (B.col3 IS NULL OR (B.col3 IS NOT NULL AND A.col3=B.col3))
--AND B.col3 IS NULL
我得到的结果如下:
col1 col2 col3 col4 ID col1 col2 col3 col4
A B 1 C I1 A B NULL C
A1 B 2 C I2 A1 B NULL C
A1 B 3 C I2 A1 B NULL C
A1 B 3 C I3 A1 B 3 C
我应该在我的选择查询中进行哪些修改(这将是我的更新查询),以便我得到如下结果:(删除第三行的结果)
col1 col2 col3 col4 ID col1 col2 col3 col4
A B 1 C I1 A B NULL C
A1 B 2 C I2 A1 B NULL C
A1 B 3 C I3 A1 B 3 C
答案 0 :(得分:1)
不幸的是,根据您提供的信息,我认为没有一个很好的通用解决方案。我需要有关可能模式的更多信息。如上所述,明显的答案是:
SELECT *
FROM #tblA a
inner join #tblb b
on a.col1=b.col1
and a.col2 = b.col2
and a.col4 = b.col4
and a.col3 = right(b.ID,1)
或者,最后一行可以是and a.col3 = coalesce(b.col3,right(b.ID,1))
这取决于#tblb中的ID在Col3中的反映。我不认为这就是你想要的。从算法的角度来看,如果你不能依赖一个有意义的ID,我不确定是否有一个很好的方法来做到这一点。如果您可以描述要应用的一般算法,那么我们可以编写代码来匹配它。
例如,可能有意义的事情是:
在某些情况下,我可以看到该算法很有用。但实际上,您正在使用重复键连接表,这会使您在重复键的记录上进行交叉连接。
希望这会有所帮助。如果你更多地澄清你想要做的事情,我可能会帮助更多。
更新:
如果正如您在评论中所说,您只想确保两个表格完全匹配,那么您可以使用以下代码:
CREATE TABLE #tblA (col1 char(2), col2 char(2), col3 int, col4 char)
CREATE TABLE #tblB (col1 char(2), col2 char(2), col3 int, col4 char)
INSERT INTO #tblA VALUES ('A','B',1,'C')
INSERT INTO #tblA VALUES ('A1','B',2,'C')
INSERT INTO #tblA VALUES ('A1','B',3,'C')
INSERT INTO #tblB VALUES ('A','B',NULL,'C')
INSERT INTO #tblB VALUES ('A1','B',NULL,'C')
INSERT INTO #tblB VALUES ('A1','B',3,'C')
delete from #tblb
where NOT Exists (Select * from #tbla a
where a.col1 = #tblb.col1
and a.col2 = #tblb.col2
and a.col3 = #tblb.col3
and a.col4 = #tblb.col4)
INSERT #tblb
SELECT * from #tbla
where not exists (select * from #tblb b
where b.col1 = #tbla.col1
and b.col2 = #tbla.col2
and b.col3 = #tbla.col3
and b.col4 = #tbla.col4)
select * from #tbla a
inner join #tblb b
on b.col1 = a.col1
and b.col2 = a.col2
and b.col3 = a.col3
and b.col4 = a.col4
当然,根据表的大小,行的大小,两个表的索引以及运行频率,简单地删除和重新插入可能更有意义。
只能更新不正确的列,但我认为编码和维护开销不值得,更不用说性能可能会非常差。
这有帮助吗?
答案 1 :(得分:0)
您不想使用内部联接,因为有多个值,您需要TOP 1或Top First记录的Col3值。
所以我更新了更新查询,如下所示,这会根据需要更新结果。
update #tblB
SET col3=
( select top 1 a.col3 from #tblA a where A.col1=#tblB.col1
AND A.col2 = #tblB.col2
AND A.col4 = #tblB.col4)
select * from #tblB