2017-03-25 90 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'更新。嘗試使用案例(何時/那麼),但得到一些相同的問題,有沒有其他方法呢? –