Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL server在多个表中进行多次更新和删除_Sql_Sql Server - Fatal编程技术网

SQL server在多个表中进行多次更新和删除

SQL server在多个表中进行多次更新和删除,sql,sql-server,Sql,Sql Server,我有四张桌子,分别是城市、地点、顾客和商店。设计此数据库的人已使主键自动递增。因此,数据库中存在冗余数据。我正在尝试清理数据库,但更新和删除行需要很长时间。这些表的示例如下所示: Table 1: City: ID_city(PK) | City | ID_City | |-----------|---------| | Chennai | 1 | | Benagluru | 2 | | Chennai | 3 | | Delhi |

我有四张桌子,分别是城市、地点、顾客和商店。设计此数据库的人已使主键自动递增。因此,数据库中存在冗余数据。我正在尝试清理数据库,但更新和删除行需要很长时间。这些表的示例如下所示:

Table 1: City: ID_city(PK)
| City      | ID_City |
|-----------|---------|
| Chennai   | 1       |
| Benagluru | 2       |
| Chennai   | 3       |
| Delhi     | 4       |
| Chennai   | 5       |
| Bengaluru | 6       |

Table 2: Location: ID_Location(PK), ID_City(FK)
| Zip  | ID_location        | ID_City |
|------|--------------------|---------|
| 0001 | 1                  | 1       |
| 0011 | 2                  | 2       |
| 0002 | 3                  | 1       |
| 0021 | 4                  | 3       |
| 0003 | 5                  | 1       |
| 0012 | 6                  | 2       |
| 0001 | 7 (duplicate of 1) | 1       |

Table 3: Customer: Cust_ID(PK), ID_Location(FK)
| Cust_ID | ID_location |
|---------|-------------|
| 1       | 1           |
| 2       | 3           |
| 3       | 5           |
| 4       | 2           |
| 5       | 7           |

Table 4: Shop: Shop_ID(PK), ID_Location(FK)
| Shop_ID | ID_location |
|---------|-------------|
| 1       | 1           |
| 2       | 2           |
| 3       | 6           |
| 4       | 3           |
| 5       | 7           |
预期表格:

如您所见,到处都有重复的记录,需要使用3个update语句(使用join和2个delete语句)来删除1个重复的城市。 有没有办法减少执行此任务的SQL语句的数量

我写的问题是:

更新客户集ID\u位置=1,其中客户ID=5 更新车间集合ID\u位置=1,其中车间ID=5 从ID_location=7的位置删除 更新位置集ID_City=1,其中ID_City=3或ID_City=5 从ID\u Location=3或ID\u Location=5的城市中删除
这是为了删除1个重复的城市,城市表中大约有1300个重复的城市。是否有一种简单的方法来检查重复项、更新并最终删除?

您可以根据条件一次性更新整个表。在您的情况下,存在另一个具有重复值的行

-- (1) UPDATE DUPLICATE CITIES ON LOCATION
UPDATE l SET l.Id_City = mstr.Id_City
-- SELECT c.Id_City oldId, mstr.Id_City newId  -- Check this for your convenience
FROM [Location] l
    INNER JOIN City c ON c.Id_City = l.Id_City 
    INNER JOIN (
        SELECT City, MIN(Id_City) Id_City -- KEEP FIRST ONLY
        FROM City
        GROUP BY City
        HAVING COUNT(1) > 1
    ) mstr ON mstr.City = c.City
        AND mstr.Id_City < Id_City

-- (2) DELETE DUPLICATE CITIES
DELETE c
-- SELECT c.Id_City oldId, mstr.Id_City newId  -- Check this for your convenience
FROM City c
    INNER JOIN (
        SELECT City, MIN(Id_City) Id_City -- KEEP FIRST ONLY
        FROM City
        GROUP BY City
        HAVING COUNT(1) > 1
    ) mstr ON mstr.City = c.City
        AND mstr.Id_City < Id_City

-- ...

其余的查询可以模拟这些示例

并不完美,但应该能够从这里开始工作

declare @City table (ID_city int primary key, City varchar(10));
insert into  @city values 
       (1, 'Chennai')
     , (2, 'Benagluru')
     , (3, 'Chennai')
     , (4, 'Delhi')
     , (5, 'Chennai')
     , (6, 'Benagluru');
--select * from @city c order by c.City, c.ID_city;

declare @Location table (ID_Location int primary key, ID_City int, zip char(4))
insert into @Location values 
       (1, 1, '0001') 
     , (2, 2, '0011')
     , (3, 1, '0002')
     , (4, 3, '0021')
     , (5, 1, '0003')
     , (6, 2, '0012')
     , (7, 1, '0001');  --duplicate
--select * from @Location l order by l.ID_Location;

declare @Customer table (Cust_ID int primary key, ID_Location int)
insert into @Customer values
       (1, 1)
     , (2, 3)
     , (3, 5)
     , (4, 2)
     , (5, 7);
--select * from @Customer;

declare @Shop table (Shop_ID int primary key, ID_Location int) 
insert into @Shop values 
       (1, 1)
     , (2, 2)
     , (3, 6)
     , (4, 3)
     , (5, 7);
--select * from @Shop s order by s.Shop_ID;

 declare @LocationMap table (ID_Location int primary key, ID_City int, zip char(4), cnt int, rn int)
 insert into @LocationMap
 select l.* 
      , count(*)     over (partition by zip) as cnt 
      , ROW_NUMBER() over (partition by zip order by ID_Location) as rn 
   from @Location l;
--select * from @LocationMap where cnt > 1 order by zip, rn;

declare @CityMap table (ID_city int primary key, City varchar(10), cnt int, rn int)
insert into @CityMap 
select c.* 
     , count(*)     over (partition by City) as cnt 
     , ROW_NUMBER() over (partition by City order by City, ID_city) as rn 
 from @City c;
--select * from @CityMap m where m.cnt > 1 order by m.City, m.ID_city;

update c 
set c.ID_Location = f.ID_Location
from @Customer c
join @LocationMap m 
  on m.ID_Location = c.ID_Location
 and m.rn > 1
join @LocationMap f 
  on f.ID_City = m.ID_City
 and m.rn = 1; 
select c.* from @Customer c order by c.Cust_ID

update s 
set s.ID_Location = f.ID_Location
from @shop s 
join @LocationMap m 
  on m.ID_Location = s.ID_Location
 and m.rn > 1
join @LocationMap f 
  on f.zip = m.zip 
 and m.rn = 1; 
select s.* from @shop s order by s.Shop_ID;

--select l.* from @Location l order by l.ID_Location;
update l 
set l.ID_City = f.ID_City
from @Location l
join @CityMap m 
  on m.ID_city = l.ID_City 
 and m.rn > 1
join @CityMap f 
  on f.City = m.City
 and f.rn = 1; 
select l.* from @Location l order by l.ID_Location;

 delete l 
 from @Location l 
 join @LocationMap m
   on l.ID_Location = m.ID_Location 
  and m.rn > 1;
select * from @Location l order by l.ID_Location;

 delete c 
 from @City c
 join @CityMap m
   on c.ID_city = m.ID_city 
  and m.rn > 1;
select * from @City c order by c.ID_city;

你能重新格式化你的数据示例吗?这是什么意思?a是编写查询的时间,b是执行查询的时间。如果是a,则不能少做,除非是在无效行上写。但我不认为编写6个查询是一个问题。如果是b,那么这更像是一个查询优化问题,您应该显示您编写的查询,并告诉我们有关表中行数的信息。@SamSegers是时候计算它们了。我在City表中有9000多行,location表中有16000多行,Customer表中有48000多行,Shop表中有4000多行。对我来说,您更新的问题与之前的评论相矛盾。你要一个接一个地写所有的查询吗?而您可能只希望每个操作/表有一个查询来执行所有更改?您更新的问题中的查询由于其简单性或多或少是最优的。@SamSegers抱歉,我的意思是逐个编写所有查询很耗时。我想知道是否所有这些都是在一个查询中完成的。可能类似于其他语言中的for循环,用于搜索重复项、进行更新和删除。
declare @City table (ID_city int primary key, City varchar(10));
insert into  @city values 
       (1, 'Chennai')
     , (2, 'Benagluru')
     , (3, 'Chennai')
     , (4, 'Delhi')
     , (5, 'Chennai')
     , (6, 'Benagluru');
--select * from @city c order by c.City, c.ID_city;

declare @Location table (ID_Location int primary key, ID_City int, zip char(4))
insert into @Location values 
       (1, 1, '0001') 
     , (2, 2, '0011')
     , (3, 1, '0002')
     , (4, 3, '0021')
     , (5, 1, '0003')
     , (6, 2, '0012')
     , (7, 1, '0001');  --duplicate
--select * from @Location l order by l.ID_Location;

declare @Customer table (Cust_ID int primary key, ID_Location int)
insert into @Customer values
       (1, 1)
     , (2, 3)
     , (3, 5)
     , (4, 2)
     , (5, 7);
--select * from @Customer;

declare @Shop table (Shop_ID int primary key, ID_Location int) 
insert into @Shop values 
       (1, 1)
     , (2, 2)
     , (3, 6)
     , (4, 3)
     , (5, 7);
--select * from @Shop s order by s.Shop_ID;

 declare @LocationMap table (ID_Location int primary key, ID_City int, zip char(4), cnt int, rn int)
 insert into @LocationMap
 select l.* 
      , count(*)     over (partition by zip) as cnt 
      , ROW_NUMBER() over (partition by zip order by ID_Location) as rn 
   from @Location l;
--select * from @LocationMap where cnt > 1 order by zip, rn;

declare @CityMap table (ID_city int primary key, City varchar(10), cnt int, rn int)
insert into @CityMap 
select c.* 
     , count(*)     over (partition by City) as cnt 
     , ROW_NUMBER() over (partition by City order by City, ID_city) as rn 
 from @City c;
--select * from @CityMap m where m.cnt > 1 order by m.City, m.ID_city;

update c 
set c.ID_Location = f.ID_Location
from @Customer c
join @LocationMap m 
  on m.ID_Location = c.ID_Location
 and m.rn > 1
join @LocationMap f 
  on f.ID_City = m.ID_City
 and m.rn = 1; 
select c.* from @Customer c order by c.Cust_ID

update s 
set s.ID_Location = f.ID_Location
from @shop s 
join @LocationMap m 
  on m.ID_Location = s.ID_Location
 and m.rn > 1
join @LocationMap f 
  on f.zip = m.zip 
 and m.rn = 1; 
select s.* from @shop s order by s.Shop_ID;

--select l.* from @Location l order by l.ID_Location;
update l 
set l.ID_City = f.ID_City
from @Location l
join @CityMap m 
  on m.ID_city = l.ID_City 
 and m.rn > 1
join @CityMap f 
  on f.City = m.City
 and f.rn = 1; 
select l.* from @Location l order by l.ID_Location;

 delete l 
 from @Location l 
 join @LocationMap m
   on l.ID_Location = m.ID_Location 
  and m.rn > 1;
select * from @Location l order by l.ID_Location;

 delete c 
 from @City c
 join @CityMap m
   on c.ID_city = m.ID_city 
  and m.rn > 1;
select * from @City c order by c.ID_city;