在Postgresql中更新查询

时间:2015-08-05 10:41:21

标签: sql postgresql sql-update dml

我在postgresql中有两个表。一个是具有列Statename和Statecode的SateTable,另一个是具有DistName,Statename和statecode列的DistTable。在DistTable中,将填充列DistName和Statename。我想更新DistTable中的“Statecode”列。请帮助。

create table Statetable (statename varchar, statecode varchar); 
create table Disttable (Distname varchar, Statename varchar, statecode varchar); 

insert into Statetable 
values 
   ('new york','NY'), 
   ('Nebraska','NB'), 
   ('Alaska','AL'); 

insert into Disttable values 
   ('King','New York', null), 
   ('salt lake','Nebraska', null), 
   ('Hanlulu','AL', null);

2 个答案:

答案 0 :(得分:1)

你要求:

(这是错误的解决方案)

update disttable 
  set statecode = st.statecode
from statetable st 
where  st.statename = disttable.statename;

但是:上述语句只会更新样本数据中的一行,因为

  1. 'new york''New York'
  2. 不同
  3. 州表中没有州名'AL'
  4. 因此两个表之间的连接只会找到(并更新)Nebraska的行。

    SQLFiddle演示:http://sqlfiddle.com/#!15/977fe/1

    正确的解决方案:

    正确的解决方案是规范化表格。给状态表一个正确的主键(状态代码可能是一个不错的选择)并且git摆脱表的无用table后缀。

    使用主键创建states表:

    create table states 
    (
       statecode varchar(2) not null primary key, 
       statename varchar
    ); 
    
    
    insert into states (statename, statecode)
    values 
       ('new york','NY'), 
       ('Nebraska','NB'), 
       ('Alaska','AL'); 
    

    分发表仅引用状态表:

    create table distributions 
    (
       -- you are missing a primary key here as well.
       Distname varchar, 
       statecode varchar not null references states
    ); 
    
    insert into distribution values 
       ('King','NY'), 
       ('salt lake','NB'), 
       ('Hanlulu','AL'); 
    

    如果需要将distname与statename一起显示,请使用join:

    select d.distname, 
           st.statename,
           st.statecode
    from distribution d
      join states s on s.statecode = d.statecode;
    

    如果您不想一直输入,请使用上述语句创建视图。

    此解决方案还避免了由于拼写错误的状态或错误的状态值而导致UPDATE与连接没有找到相应行的问题。

答案 1 :(得分:1)

如果我错了,请告诉我,但我认为你的模型应该是:

create table Statetable (statename varchar, statecode varchar); 
create table Disttable (distname varchar, statecode varchar); 

insert into Statetable 
values 
   ('new york','NY'), 
   ('Nebraska','NB'), 
   ('Alaska','AL'); 

insert into Disttable values 
   ('King','NY'), 
   ('salt lake','NB'), 
   ('Hanlulu','AL');

此外,我认为将一些标识放在可分散的位置是明智的,以便以后可以添加其他地址表。