2016-07-25 102 views
1

我最近開始了我的SQL冒險。我被要求寫出將把標題放在人名後面的查詢。標題是名稱記錄的一部分。所以如果有人姓'德約翰遜',我需要讓'約翰遜(德)'出來。我只需要選擇包含兩個單詞的名字(標題)。我已經找到了正確的解決這個問題,這裏是查詢:SQL重新排序的字

SELECT SUBSTR(naam, INSTR(naam,' ')+1) || ' (' || LOWER(SUBSTR(naam, 1, INSTR(naam, ' ') -1)) || ')' 
FROM medewerkers 
WHERE naam like '% %'; 

現在是我的問題,是有可能使其更詳細?我真的更多地使用CONCAT來代替||等等。我不明白混合SQL和唱歌的概念。我知道這個查詢沒有任何意義,因爲SQL沒有用於格式化輸出,但是我正在爲學校做這些(他們甚至不能像SQL那樣簡單地教會)。

+0

請注意,你可以做到這一點很好地與'REGEXP_REPLACE(N aam,'^(\ S +)\ s +(。*)$','\ 2(\ 1)')',然後您可以省略where子句。 – trincot

+0

使用||是正常的。 CONCAT在這裏會很難看。 – Mottor

+0

學習使用||更好並以「找到它的正常方式」進行連接。在Oracle中,'concat()'只能**接受兩個參數(只有Oracle知道爲什麼);如果您必須連接四個字符串,則需要使用'concat()'三次。 – mathguy

回答

2

,而不是把這個成等價的CONCAT表達的,我會提出一個解決方案,這也將:

  • 將更多一點的話就結束條件,他們不大寫字母開頭的,除了第一個。例如:「Van den Heuvel」將成爲「Heuvel(Van den)」;
  • 從開始和結束脩剪空格:這樣可以避免在開始或結束時使用空格存儲的名稱的奇怪效果。
  • 如果沒有可以移動到括號內的單詞,則返回一個不變的名稱。這很有用,因爲您可以排除where子句並在結果集中包含所有名稱。

對於此任務,正則表達式派上用場:

select regexp_replace(trim(naam), '^(\S+(\s+[^A-Z]\S*)*)\s+(\S.*)$', '\3 (\1)') 
from medewerkers 

函數的最後一個參數是在展示時,有一個匹配所產生的格式相當的可讀性。

注:根據語言設置(即NLS_SORT,不區分大小寫的排序),它可能需要更多的參數添加到preg_replace執行區分大小寫:

select regexp_replace(trim(naam), '^(\S+(\s+[^A-Z]\S*)*)\s+(\S.*)$', '\3 (\1)', 1, 0, 'c') 
from medewerkers 

這裏有一些測試案例:

select id, naam, 
     regexp_replace(trim(naam), '^(\S+(\s+[^A-Z]\S*)*)\s+(\S.*)$', '\3 (\1)') 
      as corrected 
from (select 1 id, 'De Ridder' as naam from dual union 
     select 2, ' de Meester' from dual union 
     select 3, 'Smits' from dual union 
     select 4, 'Vandenborre ' from dual union 
     select 5, 'Van den Borre' from dual union 
     select 6, ' van der Meulen' from dual union 
     select 7, 'van ''t Oosten' from dual union 
     select 8, 'Van de Walle-Van der Meulen' from dual) 
order by id; 

輸出:

id | naam      | corrected 
---+-----------------------------+------------------ 
1 | De Ridder     | Ridder (De) 
2 | de Meester     | Meester (de) 
3 | Smits      | Smits 
4 | Vandenborre     | Vandenborre 
5 | Van den Borre    | Borre (Van den) 
6 | van der Meulen    | Meulen (van der) 
7 | van 't Oosten    | Oosten (van 't) 
8 | Van de Walle-Van der Meulen | Walle-Van der Meulen (Van de) 
+0

感謝您的編輯,@Mottor! – trincot

+0

我沒有得到相同的結果(編號5,6和8) – Mottor

+0

雖然這當然是一個很好的解決方案(並且可能會在未來幫助其他論壇成員),但它是否會幫助OP清楚地解釋他剛剛開始學習Oracle和SQL。此外,它沒有達到其中一項要求; OP在他的解決方案中有一個'LOWER()',這看起來是有意的,而不是在這個解決方案中重現的。 – mathguy