SQL将2行合并为1行,然后删除1

时间:2019-03-04 00:40:49

标签: sql

我正在尝试完成一个SQL查询作业问题,并且无法弄清楚如何从同一张表中添加两行,目的是在合并后删除一行。

我有一个表名“ country”,其中有241行数据和列。

name        region           area          population     GDP
------------------------------------------------------------------------
Hong Kong   Southeast Asia      1040          5542869      136100000000
China       Asia             9596960       1203097268     2978800000000 

预期输出:

name        region           area       population    GDP
-------------------------------------------------------------------
Hong Kong   Southeast Asia      1040       5542869     136100000000
China       Asia             9598000    1208640137    3114900000000

目标是将行的名称保持为“中国”,将区域名称保持为“亚洲”,但将“香港”行的数值添加到“中国”行中的列(区域,人口,和GDP)。

我已经尝试了UNION和MERGE,但是我对使用它们并不熟悉,因此无法正常工作。

我觉得它必须类似于下面的SQL查询:

update country 
set area = area.HongKong + area.China 
where name = 'China';

但是我不知道引用特定行的正确方法。

1 个答案:

答案 0 :(得分:0)

是的,功课。我记得那些日子。

这里有一些代码可以帮助您-

--create a temp table to hold sample data
select
*
into #country
from
(
  values
  ('Hong Kong', 'Southeast Asia', 1040, 5542869, 136100000000),
  ('China', 'Asia', 9596960, 1203097268, 2978800000000),
  ('USA', 'North America', 1, 10, 100)  --some other row in table
) d ([name], region, area, population, gdp);

select * from #country;

这是该表中的数据: enter image description here

--update statement
with
Totals as
(
  select
  count(1) rows,  --should be 2
  sum(area) areaTotal,
  sum(population) populationTotal,
  sum(gdp) gdpTotal
  from #country
  where [name] in ('Hong Kong', 'China') --this filter may be insufficient; it would be better to select by a primary key such as a rowID but the table does not have one
)
update c
set c.area = t.areaTotal,
c.population = t.populationTotal,
c.gdp = t.gdpTotal
from #country c
inner join totals t
on c.[name] = 'China';

以下是更新后数据的样子: enter image description here

这里有一些值得注意的事情:

  1. 更新语句with Totals as (...上方的代码称为通用表表达式(也缩写为CTE)。它在此处用于包含查询,该查询计算执行更新所需的总数。 CTE是创建中间数据集的一种方法。替代方法包括:创建临时表或使用派生表。
  2. 要在CTE中查看查询结果,可以在编辑器中突出显示这些代码行,并针对数据库执行这些代码。
  3. 原始帖子说国家表中有241行数据。这意味着在查询中有一个可靠的过滤器来计算总数很重要,这样就可以隔离正确的求和行。筛选行的首选方法是使用主键,例如rowID。由于该表没有主键列,因此我进行了猜测并使用了[name]列。
  4. CTE中count(1) rows的目的是确保只对2行进行求和。如果该数字返回2以外的其他值,则表示过滤器存在问题,并且需要修改where子句。行数仅在您执行上面的#2时可见。

现在需要清理香港行:

--delete old row
delete from #country where [name] = 'Hong Kong';

现在的数据如下:
enter image description here
再次,最好在where子句中使用主键列,而不是[name]列,以确保删除了正确的行。