我有
表XXX
ID int
CODE varchar
表格YYY
ID int
X_ID int
导入中的分隔符错误导致一些记录在我的表中两次进入。发生了什么?我不确定。结果就是:表XXX中的两个记录都指的是同一个实体,作为'之前的CODE的一部分;'是一样的。
表XXX
ID | Code
123 | 456
789 | 456;li
表YYY
ID | X_ID
111 | 789
222 | 123
333 | 000
现在我需要一个查询来为我需要更新的所有2900条记录执行此操作: 我需要保留YYY中的所有记录。
将表YYY中记录111的X_ID更新为123,然后从中删除记录789 表XXX
不需要在1个查询中执行此操作。 那我该怎么办呢?你能帮助我吗? 我写了很多半查询,我觉得自己像一个菜鸟(我在SQL中)
答案 0 :(得分:1)
这就是我想出的。 事实证明,还有一个表需要更新。 再次感谢MiHaiC的努力。我的答案给了你灵感。
WITH WA AS (
SELECT ID AS BID,
Code AS BCode
FROM XXX
)
SELECT a.id as 'FOUT_ID',
b.Bid as 'GOED_ID',
a.code as 'FOUTE_CODE',
b.Bcode as 'GOEDE_CODE'
INTO TEST_QUERY
from XXX a
INNER JOIN WA b ON b.BCode = substring (a.code, 1, charindex (';', a.code,0 ) - 1)
where a.prs_Code like '%;%'
UPDATE YYY
SET X_ID = TEST_QUERY.GOED_ID
FROM YYY
INNER JOIN TEST_QUERY ON TEST_QUERY.FOUT_ID = X_ID
WHERE ID IN (
SELECT ID
FROM ZZZ
INNER JOIN TEST_QUERY ON TEST_QUERY.FOUT_ID = ZZZ.ID)
UPDATE ZZZ
SET ID = TEST_QUERY.GOED_ID
FROM ZZZ
INNER JOIN TEST_QUERY ON TEST_QUERY.FOUT_ID = D_Melding.mld_prs_ID
希望这可以帮助别人。
答案 1 :(得分:0)
第一次查询:
UPDATE YYY SET X_ID=123 WHERE ID=111
相反,您也可以执行WHERE X_ID=789
并获得相同的结果。
第二次查询:
DELETE FROM XXX WHERE ID=789
答案 2 :(得分:0)
对不起,它花了一点时间,我发现的唯一快速解决方案,因为不让你久等不及是使用一个程序:
CREATE OR REPLACE PROCEDURE FIX_XXX_YYY
IS
BEGIN
--make changes in XXX, to remove delimiter, such that we can get min/max with group by code
UPDATE XXX
SET code = SUBSTR (code, 1, INSTR (code, ';') - 1)
WHERE INSTR (code, ';') > 0;
COMMIT;
--update YYY with the correct values by using min/max(id) from XXX, min = first entry so the good one, max =bad entry.
--basically update all bad entries in YYY with corresponding good value in XXX
FOR entry IN ( SELECT MIN (id) AS good_id, MAX (id) AS bad_id, code
FROM xxx
GROUP BY code
HAVING COUNT (1) > 1)
LOOP
UPDATE yyy
SET x_id = entry.good_id
WHERE x_id = entry.bad_id;
COMMIT;
END LOOP;
--delete the duplicates from XXX, i.e the bad entries represented by MAX
DELETE FROM xxx
WHERE id IN (SELECT id
FROM (SELECT id,
code,
MAX (id) OVER (PARTITION BY code) max_id
FROM xxx)
WHERE id = max_id);
COMMIT;
RETURN;
END FIX_XXX_YYY;
使用以下方法调用它:
BEGIN
FIX_XXX_YYY;
COMMIT;
END;
希望这次我做对了。请测试并告诉我。我会删除错误的答案。
答案 3 :(得分:0)
我在之前的回答中犯了一个错误,因为我给出的解决方案是Oracle数据库。 OP需要sqlserver的解决方案。
我已将我的代码翻译成sql:
begin transaction
declare @good_id int
declare @bad_id int
declare @code varchar(128)
--update xxx as to change the lines containing ';' to just the number value. we do this by removing
--every character after ';' including ';'.
--we will use the updated values to calculate min and max over the id column
update XXX set code=SUBSTRING(code,1,CHARINDEX(';',code) - 1) where CHARINDEX(';',code)>0
--declare a cursor to calculate min (the good_id) and max (the bad_id) for a given code in table XXX
--this assumes the wrong id is always inserted secondly, i.e. it's value is always greater than the good id
declare myCursor cursor local fast_forward for
SELECT MIN (id) AS good_id, MAX (id) AS bad_id, code
FROM xxx
GROUP BY code
HAVING COUNT (1) = 2 --this condition is used to filter only duplicate entries, i.e only those entries in XXX that have the same code twice!
open myCursor
while 1=1 --while true
BEGIN
fetch next from myCursor into @good_id, @bad_id, @code --save the values obtained from the cursor in local variables
if @@FETCH_STATUS<>0 --when there is nothing left to fetch from the cursor we exit the while loop
begin
break
end
--update YYY with the correct values by using min/max(id) from the variables @good_id and @bad_id
update YYY set x_id=@good_id where x_id=@bad_id;
END --end while loop
close myCursor
deallocate myCursor
--delete the duplicates from XXX, i.e the bad entries represented by MAX
delete from XXX where id in(
select id from (
SELECT id,code,MAX (id) OVER (PARTITION BY code) as max_id FROM xxx) x where id=max_id)
commit transaction --save changes
测试了这组数据的代码:
Table XXX id code 123 456 456 999 789 456;li 932 999;ab
Table YYY id x_id 111 789 222 123 333 000 444 932 555 456
运行后:
Table XXX id code 123 456 456 999
Table YYY id x_id 111 123 222 123 333 000 444 456 555 456OP,请告诉我它是否适合你。如果您对代码有任何疑问,我很乐意回答。