2017-03-25 159 views
4

是否可以通过连接来自另一个表的列数据来更新一个表列数据?让我用简单的例子说明,用两个表连接一列

表A:studentaccess

╔════════╦══════════╗ 
║ UserID ║ AccCode ║ 
╠════════╬══════════╣ 
║ 12 ║ Tom  ║ 
║ 13 ║ Ann  ║ 
╚════════╩══════════╝ 

表B:studentdetails

╔════════╦═══════════════════╗ 
║ ID  ║ UserName   ║ 
╠════════╬═══════════════════╣ 
║ 1 ║ raj_12_kumar  ║ 
║ 2 ║ test_13_test  ║ 
╚════════╩═══════════════════╝ 

现在我要分割UserName列数据,并获取从第二令牌和通过匹配UserID查询studentaccess表,并从中获取AccCode值,并将其与UserName列数据的第二个标记串联起来。最后,我需要studentdetails表中的数据类似下面,

╔════════╦═══════════════════╗ 
║ ID  ║ UserName   ║ 
╠════════╬═══════════════════╣ 
║ 1 ║ 12_Tom   ║ 
║ 2 ║ 13_Ann   ║ 
╚════════╩═══════════════════╝ 

从以下SUBSTR查询我可以从studentdetailsUserName列得到UserId值,

select regexp_substr(UserName, '([^_]+)(_[^_]+){1}$', 1, 1, null, 1) as userId from studentdetails 

任何一个可以帮助我来连接与Acccode相同并且在UserName列中更新相同?

+0

你标记的4个不同的数据库。你实际使用哪一个? –

+0

Oracle数据库 –

+0

你标记了其他DBMS系统,但不是甲骨文? –

回答

1

您可以使用下面的查询,我已经测试过,并在我结束验证。

您可以在此sqlfiddle检查出的Oracle版本:http://sqlfiddle.com/#!4/cd66c/1

Oracle版本

UPDATE studentdetails sd 
SET sd.UserName = 
    (SELECT to_char(x.UserID) || '_' || sa.AccCode 
    FROM 
    (SELECT sd1.ID as ID, SUBSTR(sd1.UserName, INSTR(sd1.UserName,'_') + 1, INSTR(sd1.UserName,'_', INSTR(sd1.UserName,'_') + 1) - 1 - INSTR(sd1.UserName,'_')) AS UserID 
     FROM studentdetails sd1 
    ) x INNER JOIN studentaccess sa ON TO_NUMBER(x.UserID) = sa.UserID where sd.ID = x.ID 
); 

SQL Server版本

UPDATE studentdetails 
SET UserName = 
    (SELECT x.UserID + '_' + sa.AccCode 
    FROM 
    (SELECT SUBSTRING(sd1.UserName, CHARINDEX('_', sd1.UserName) + 1, CHARINDEX('_', sd1.UserName, CHARINDEX('_', sd1.UserName) + 1) - 1 - CHARINDEX('_', sd1.UserName)) AS UserID 
     FROM studentdetails sd1 
     WHERE sd1.ID = studentdetails.ID) x 
    INNER JOIN studentaccess sa ON x.UserID = sa.UserID); 

更新1

如果您希望studentdetails表的列UserName中的字符串UNKNOWN(如果studentaccess表不包含从studentdetails表中获得的UserID),则可以使用该查询。

我无法在sqlfiddle中尝试它,因为sqlfiddle由于某些问题而没有加载。每当它回到网上,我都会尝试一下,让你知道。与此同时,您可以尝试一下,并告诉我任何问题。

UPDATE studentdetails sd 
SET sd.UserName = 
    (SELECT CASE when x.ID is null then 'UNKNOWN' else to_char(x.UserID) || '_' || sa.AccCode END 
    FROM 
    (SELECT sd1.ID as ID, SUBSTR(sd1.UserName, INSTR(sd1.UserName,'_') + 1, INSTR(sd1.UserName,'_', INSTR(sd1.UserName,'_') + 1) - 1 - INSTR(sd1.UserName,'_')) AS UserID 
     FROM studentdetails sd1 
    ) x RRIGHT OUTER JOIN studentaccess sa ON TO_NUMBER(x.UserID) = sa.UserID where sd.ID = x.ID 
); 
+0

您的解决方案也按预期工作,但我需要对查询进行一些修改。就像它发现与sa匹配一样。userId那么它应该更新concatinated字符串,否则它应该用String'UNKNOWN'更新。尝试使用案例(何时/那么),但得到一些相同的问题,有没有其他方法呢? –

+0

@SQLLearner,所以,如果studentaccess表不包含UserID,那么更新到UNKNOWN。那是对的吗? – Sunil

+0

@SQLLearner,尝试更新1下的查询,并让我知道。 – Sunil

0

你快要近了。您可以将其他列与userName连接起来。

regexp_substr(UserName, '([^_]+)(_[^_]+){1}$', 1, 1, null, 1) || '_' || acccode 

结果与你的样本数据会是这样 -

select userid, regexp_substr(UserName, '([^_]+)(_[^_]+){1}$', 1, 1, null, 1) || '_' || acccode as username from 
(
select 1 UserID, 'Tom' AccCode from dual 
union 
select 1 userid , 'Ann' AccCode from dual) studentaccess, 
(select 1 ID, 'raj_12_kumar' username from dual 
union 
select 2 id, 'test_13_test' username from dual) studentdetails 
where studentaccess.userid = studentdetails.ID 
2
UPDATE StudentDetails sd 
SET UserName = 
( 
    SELECT userid||'_'||AccCode 
    FROM StudentAccess sa 
    WHERE regexp_substr(sd.UserName, '([^_]+)(_[^_]+){1}$', 1, 1, null, 1) = sa.userid 
); 
+0

它按预期工作,需要在查询中进行一些修改。就像它发现与sa.userid匹配,那么它应该更新cncatinated字符串,否则它应该用String'UNKNOWN'更新。尝试使用案例(何时/那么),但得到一些相同的问题,有没有其他方法呢? –