web-dev-qa-db-ja.com

連結でIf Not Nullを使用するSQL

テーブルがある場合

enter image description here

SELECT (Firstname || '-' || Middlename || '-' || Surname)  AS example_column
FROM example_table

これにより、Firstname-Middlename-Surnameが表示されます。

John--Smith
Jane-Anne-Smith

2番目(ジェーン)は正しいと表示されますが、ジョンにはミドルネームがないため、2番目のダッシュは無視してください。

どうすればIF Middlename = NULLステートメントを入れて、John-Smithだけを表示できますか

12
BiscuitCookie

ここに私の提案があります:

PostgreSQLおよびその他のSQLデータベース('a' || NULL IS NULL、次に [〜#〜] coalesce [〜#〜] を使用します。

SELECT firstname || COALESCE('-' || middlename, '') || '-' || surname ...

Oracleおよびその他のSQLデータベース('a' || NULL = 'a'

SELECT first name || DECODE(middlename, NULL, '', '-' || middlename) || '-' || surname...

私は簡潔さを求めています。ここで、ミドルネームが空かどうかは、メンテナンスプログラマにとってはあまり興味深いことではありません。 CASEスイッチはまったく問題ありませんが、かさばります。可能な限り、同じ列名( "ミドルネーム")を繰り返さないようにします。

@Prdpが指摘したように、答えはRDBMS固有です。具体的には、サーバーがNULLと同等の長さゼロの文字列を処理するかどうかであり、NULLを連結するとNULLが生成されるかどうかが決まります。

通常、COALESCEはPostgreSQLスタイルの空文字列の処理に最も簡潔であり、DECODE (*VALUE*, NULL, ''...は、Oracleスタイルの空の文字列を処理します。

20
Andrew Wolfe

Postgresを使用している場合、concat_ws()が探しています:

_SELECT concat_ws('-', Firstname, Middlename, Surname)  AS example_column
FROM example_table
_

SQLFiddle: http://sqlfiddle.com/#!15/9eecb7db59d16c80417c72d1e1f4fbf1/8812

空の文字列またはNULLなどのスペースのみを含む文字列を処理するには、nullif()を使用します。

_ SELECT concat_ws('-', Firstname, nullif(trim(Middlename), ''), Surname)  AS example_column
 FROM example_table
_
10

このアプローチ works

select first_name || coalesce('-' || middle_name, '') || '-' || last_name 
from t;

出力:

|        ?column? |
|-----------------|
|      john-smith |
| jane-anne-smith |

[〜#〜] update [〜#〜]

ライブコード: http://sqlfiddle.com/#!15/d5a1f/1

筆者のように、誰かが問題になっていないシナリオを提供します。したがって、空のミドルネームで動作するようにします。空の文字列にnullifを追加するだけです:

select first_name || coalesce('-' || nullif(middle_name,'') , '') || '-' || last_name 
from t;

出力:

|        ?column? |
|-----------------|
|      john-smith |
|      obi-kinobi |
| jane-anne-smith |
1
Michael Buen

これは実行可能なオプションです。

SELECT FirstName || '-' || ISNULL(MiddleName + '-', '') || Surname

文字列と連結されたNULLはNULLを生成するため、サブ文字列を作成し、NULLを空の文字列に置き換えて、名前の次の部分に連結することができます。

これは、FirstNameとSurnameが常にNULLではないことを前提としていますが、同じロジックを適用することもできます。

1
Shoeless

1つの解決策はcase statement

select case Middlename is not null then (Firstname || '-' || Middlename || '-' || Surname) 
    else (Firstname || '-' || Surname) end AS example_column
from ....
1
Pham X. Bach

REPLACEを使用できます(Oracleの場合)

SELECT
   REPLACE(Firstname || '-' || Middlename || '-' || Surname,'--','-') 
   AS example_column
FROM example_table;

警告:最初の文字または最後の文字として-を持つ有効な名前はないと仮定しました。


ダウンボターの場合

OPは明確に次のように述べました。

SELECT (Firstname || '-' || Middlename || '-' || Surname)  AS example_column
FROM example_table

これにより、Firstname-Middlename-Surnameが表示されます。

ジョン-スミス

そう:

  1. Middlenameは空白です:''このソリューションはSQLite/PostgreSQL/Oracleで動作します
  2. MiddlenameNULLであり、OPはおそらく Oracle を使用します

Oracleは長さゼロの文字列をNULLとして扱いますが、長さゼロの文字列を別のオペランドと連結すると、常に他のオペランドになります。

||連結演算子:

 -- PostgreSQL/SQLite
 SELECT 'sth' || NULL
 -- NULL


 -- Oracle
 SELECT 'sth' || NULL
 -- sth
0
Lukasz Szozda
  • NULLIF式は、空白のMiddlenameNULLに減らします
  • 連結'-'NULLを指定すると、常にNULLが返されます
  • VALUE式はNULLsを空の文字列に置き換えます

_

SELECT Firstname || VALUE( '-' || NULLIF('Middlename',''),'') || '-' || Surname'  
       AS example_column
FROM example_table
0
Stavr00

CASEステートメントを使用できます

select Firstname 
      || case when Middlename <> '' Then '-'||Middlename  else '' END 
      || case when Surname<> '' Then '-'||Surname else '' END

サンプルデータに従って、empty stringを確認します。 NULLを確認するには、Middlename IS NOT NULLの代わりにMiddlename <> ''を使用します

0