SQL 文字列結合メモ

#はじめに
SQLでの文字列結合に関しての備忘録です。
RDBMSによって使用できる関数が異なりますが、今回はSQL Server向けの内容をまとめていきます。

# `文字列の結合について`
SQL Serverにおける文字列結合の方法としては、大きく下記の2つに分けられます。

**・+を利用して文字列同士の結合を行う方法**
+を使用した場合には、文字列の結合しかできませんので(同じデータ型同士しか結合できません)、
数値型や日付型など、文字列以外のデータを結合する場合には、
CONVERT、FORMAT、CAST等の変換関数を使用して、文字列に型変換を行う必要があります。

**・NULL項目を考慮し、CONCATを使用する方法**
CONCAT関数を使用する利点は、NULL項目を自動で空白項目に置き換えてくれる点にあります。
NULLを許容しているカラムの文字列結合においては、CONCAT関数を使用するほうが良さそうです。 

# `+を利用して結合`
**①文字列型同士で結合したい**
・文字列同士を結合して表示(リテラル)

```bash
SELECT 'テスト' +  '文字列結合' AS 結果
```

![1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387837/79a30d9c-bcda-6f62-dc53-7755349da356.jpeg)
・文字列同士を結合して表示(列名)

```bash
SELECT 列名1 + 列名2 FROM テーブル名
```

・文字列同士を結合して表示(リテラル + 列名)

```bash
SELECT 'テスト' + 列名1 FROM テーブル名
```

**(※)NULLデータを含む場合**
文字列とNULLを+で結合すると、結果はNULLで返ってくるため注意が必要です。

```bash
SELECT 'テスト' +  NULL AS 結果
```

![2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387837/92bf0ee2-0138-edc6-e08b-390ae6bbd781.jpeg)


ISNULLを使用するなどして、NULLを空白スペースに明示的に置き換える必要があります。

```bash
SELECT 'テスト' +  ISNULL(NULL, '') AS 結果
```

**②異なるデータ型と結合したい**
各関数のstyleやculture については、ページ下部を参照してください。

`数値型と結合`

・CONVERTを使用

```bash
SELECT '文字列1' + CONVERT(NVARCHAR, 数値型のデータ)
```

・CASTを使用

```bash
SELECT '文字列1' + CAST(数値型のデータ AS varchar)
```

`日付型と結合`
・CONVERTを使用

```bash
SELECT '文字列1' + CONVERT(NVARCHAR, 日付型のデータ [, style])
```

・FORMATを使用

```bash
SELECT '文字列1' + FORMAT(日付型のデータ,FORMAT [,culture ])
```





# `CONCATを利用して結合`
**①文字列型同士で結合したい**

・文字列同士を結合して表示(リテラル)

```bash
SELECT CONCAT('テスト' ,'文字列結合') AS CONCATの戻り値
```

![4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387837/aa138757-56d1-b7d3-665d-83a9a6d8cd4c.jpeg)

・文字列同士を結合して表示(列名)

```bash
SELECT CONCAT(列名1 , 列名2 ) FROM テーブル名
```

・文字列同士を結合して表示(リテラル + 列名)

```bash
SELECT CONCAT(‘文字列1’ , 列名1 ) FROM テーブル名 
```

**(※)NULLデータを含む場合**
CONCATはNULL項目を自動で空白スペースに置き換えてくれますので、ISNULLを使用したりする必要はありません。 

```bash
SELECT CONCAT('テスト' ,NULL) AS CONCATの戻り値
```

![5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387837/faa2554d-d622-17a0-0f63-11164cb6c791.jpeg)



**②異なるデータ型と結合したい**
`数値型と結合`
・CONVERTを使用

```bash
SELECT CONCAT(‘文字列1’ , CONVERT(NVARCHAR, 数値型のデータ))
```

・CASTを使用

```bash
SELECT CONCAT(‘文字列1’ , CAST(数値型のデータ AS VARCHAR)) 
```

`日付型と結合`
・CONVERTを使用

```bash
SELECT CONCAT(‘文字列1’ , CONVERT(NVARCHAR, 日付型のデータ [, style]))
```

・FORMATを使用

```bash
SELECT CONCAT(‘文字列1’ , FORMAT(日付型のデータ,FORMAT [,culture ]))
```

**番外編**
CONCATを用いて、更新とか検索とかソートとか

・(リテラル + 列名)の値で更新したい

```bash
UPDATE テーブル名 SET 更新先列名 = CONCAT('文字列1',`元列名`);
```

・複数の列名を結合してまとめて検索したい

```bash
SELECT * FROM テーブル名 WHERE CONCAT('列名1', '列名2') = '検索文字列'
```

・ソートしたい

| テスト列名 |
|---|
|ABC1|
|ABC11 |
|ABC12|
|ABC13|
|ABC2|
|ABC3|

上記のデータを並び替えるとき、次のクエリを実行すると、

```bash
SELECT * FROM テーブル名 ORDER BY テスト列名;
```

![8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387837/3de13d71-c846-8922-55d2-8c48db6add90.jpeg)


という順番になってしまいます。

そこで、以下のSQLを実行すると、

```bash
SELECT * FROM テーブル名 ORDER BY RIGHT(CONCAT('00', SUBSTRING(テスト列名, 4 ,2)),2)
```

![9.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387837/33cd8076-b92c-7843-8a55-42c5a2bc7aa3.jpeg)


の順番でデータを取得することができます。


#参考ページ
[CAST および CONVERT](https://docs.microsoft.com/ja-jp/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-2017)
[FORMAT](https://docs.microsoft.com/ja-jp/sql/t-sql/functions/format-transact-sql?view=sql-server-2017)
[CONCAT](https://docs.microsoft.com/ja-jp/sql/t-sql/functions/concat-transact-sql?view=sql-server-2017)