2011-09-22 137 views
5

我有一堆用戶在我的數據庫中,我想重置他們的所有用戶名到他們的名字的第一個字母,加上他們的全名。你可以想象,有一些愚蠢的行爲。在這種情況下,我想在用戶名的末尾添加「2」或「3」或其他內容。我將如何編寫一個查詢來生成這樣的唯一用戶名?從名字和姓氏生成唯一的用戶名?

UPDATE user 
SET username=lower(concat(substring(first_name,1,1), last_name), UNIQUETHINGHERE) 

回答

5
CREATE TABLE bar LIKE foo; 

INSERT INTO bar (id,user,first,last) 
(SELECT f.id,CONCAT(SUBSTRING(f.first,1,1),f.last, 
    (SELECT COUNT(*) FROM foo f2 
     WHERE SUBSTRING(f2.first,1,1) = SUBSTRING(f.first,1,1) 
       AND f2.last = f.last AND f2.id <= f.id 
     )),f.first,f.last from foo f); 

DROP TABLE foo; 
RENAME TABLE bar TO foo; 

這依賴於一個主鍵id,所以對於每個記錄插入到bar,我們只比bar.idid算上foo發現重複。

鑑於FOO:

select * from foo; 
+----+------+--------+--------+ 
| id | user | first | last | 
+----+------+--------+--------+ 
| 1 | aaa | Roger | Hill | 
| 2 | bbb | Sally | Road | 
| 3 | ccc | Fred | Mount | 
| 4 | ddd | Darren | Meadow | 
| 5 | eee | Sharon | Road | 
+----+------+--------+--------+ 

上面INSERT s轉換bar,導致:

select * from bar; 
+----+----------+--------+--------+ 
| id | user  | first | last | 
+----+----------+--------+--------+ 
| 1 | RHill1 | Roger | Hill | 
| 2 | SRoad1 | Sally | Road | 
| 3 | FMount1 | Fred | Mount | 
| 4 | DMeadow1 | Darren | Meadow | 
| 5 | SRoad2 | Sharon | Road | 
+----+----------+--------+--------+ 

爲了除去從 「1」 的用戶名的末尾,

INSERT INTO bar (id,user,first,last) 
(SELECT f3.id, 
     CONCAT(
      SUBSTRING(f3.first,1,1), 
      f3.last, 
      CASE f3.cnt WHEN 1 THEN '' ELSE f3.cnt END), 
     f3.first, 
     f3.last 
FROM (
    SELECT 
     f.id, 
     f.first, 
     f.last, 
     (
      SELECT COUNT(*) 
      FROM foo f2 
      WHERE SUBSTRING(f2.first,1,1) = SUBSTRING(f.first,1,1) 
      AND f2.last = f.last AND f2.id <= f.id 
     ) as cnt 
    FROM foo f) f3) 
+0

什麼是酒吧?爲什麼最後有三重報價?謹慎解釋這一點? – mpen

+0

@Mark:'bar'是一個像'foo'這樣的空表。將記錄插入'bar'後,可以放棄'foo'並重命名'bar' - >'foo'。三重引號是Python的工件,我測試了代碼。 – unutbu

+0

啊。我只想更新用戶表,但我想我可以輕鬆地將其轉回。這很酷。如果它是「1」,我也會忽略這個數字,但是再次,這應該很容易做到。太好了!非常感謝! **編輯:**像你的評論解釋。 – mpen

3

爲兩舞伴:

SELECT max(username) 
FROM user 
WHERE username LIKE concat(lower(concat(substring(first_name,1,1),lastname), '%') 

檢索該名稱組合 「最高」 的用戶名。提取數字後綴,將其增加,然後插入數據庫以供新用戶使用。

當然這很活潑。具有相同姓氏/名字的兩個用戶可能會踩踏對方的用戶名,具體取決於情況。您一定要在查詢上添加一些事務/鎖定,以確保您沒有任何用戶衝突。

+0

我希望用純MySQL來做到這一點...這需要我遍歷所有用戶,不? – mpen

0

Neve rmind ....我剛剛發現了這些軟件:

select LOWER(CONCAT(SUBSTRING(first_name,1,1),last_name)) as new_login,count(*) as cnt from wx_user group by new_login having count(*)>1; 

並手動設置這些。只有少數。

1

在unutbu的回答啓發:沒有必要創建一個額外的表沒有幾個疑問:

UPDATE USER a 
    LEFT JOIN (
     SELECT USR_ID, 
      REPLACE(
       CONCAT(
        SUBSTRING(f.`USR_FIRSTNAME`,1,1), 
        f.`USR_LASTNAME`, 
        (
         (SELECT IF(COUNT(*) > 1, COUNT(*), '') 
          FROM USER f2 
          WHERE SUBSTRING(f2.`USR_FIRSTNAME`,1,1) = 
           SUBSTRING(f.`USR_FIRSTNAME`,1,1) 
           AND f2.`USR_LASTNAME` = f.`USR_LASTNAME` 
           AND f2.`USR_ID` <= f.`USR_ID`) 
         ) 
       ), 
       ' ', 
       '') as login 
     FROM USER f) b 
    ON a.USR_ID = b.USR_ID 
    SET a.USR_NICKNAME = b.login 
+0

我盡了最大努力爲此添加了足夠的縮進以使其可讀,但此​​查詢在寫入方式上有點怪異。 –

+0

爲什麼downvote?它可能是可怕的,但它的工作原理和它可以幫助人們,我有同樣的問題,這是我找到的解決方案,downvoting這表明這是錯誤的想法! – Batato

+0

我沒有降低它的效果,但正如最初的回答,缺乏縮進使其無法讀取。我打賭這就是爲什麼。 [但問:「爲什麼downvote?」在這裏通常被認爲是不好的風格。](http://meta.stackoverflow。com/questions/252826/is-asking-reason-for-downvote-in-comments-non-constructive) –

相關問題