【Snowflake】SnowflakeとSQLServerのデータ型変換早見表をつくってみた

# はじめに
データ型の一覧と業務で実際利用した変換早見表を共有したいと思います。
また、SQLServerでstyleを使用した構文をSnowflakeに落とし込む方法も少し書きました。

SQLServerとSnowflake特効記事になります。(他にも互換性があればよいのですが・・・)

# 目次
1.前提
2.SQLServerのデータ型
3.Snowflakeのデータ型
4.データ型変換
おまけ.SQLServerのスタイル(style)から書き換え
おわりに

# 1.前提
データ型の基本がある程度理解できていること

# 2.SQLServerのデータ型
MSドキュメントに記載されているデータ型を表にしてみたものです。
結構多いですね

| カテゴリ | 型 | 注意 |
|:------------|:------------|:------------|
| 真数　　　　　　 | bigint ||
| 真数　　　　　　 | numeric ||
| 真数　　　　　　 | bit ||
| 真数　　　　　　 | smallint ||
| 真数　　　　　　 | decimal ||
| 真数　　　　　　 | smallmoney ||
| 真数　　　　　　 | int ||
| 真数　　　　　　 | tinyint ||
| 真数　　　　　　 | money ||
| 概数　　　　　　 | float ||
| 概数　　　　　　 | real ||
| 日付と時刻　　　 | date ||
| 日付と時刻　　　 | datetimeoffset ||
| 日付と時刻　　　 | datetime2 ||
| 日付と時刻　　　 | smalldatetime ||
| 日付と時刻　　　 | datetime ||
| 日付と時刻　　　 | time ||
| 文字列          | char ||
| 文字列          | varchar ||
| 文字列          | text ||
| Unicode 文字列  | nchar ||
| Unicode 文字列  | nvarchar ||
| Unicode 文字列  | ntext ||
| バイナリ文字列　 | binary ||
| バイナリ文字列　 | varbinary ||
| バイナリ文字列　 | image ||
| その他のデータ型 | cursor ||
| その他のデータ型 | rowversion ||
| その他のデータ型 | hierarchyid ||
| その他のデータ型 | uniqueidentifier ||
| その他のデータ型 | sql_variant ||
| その他のデータ型 | xml ||
| その他のデータ型 | geometry |平面空間データ型　ユークリッド (平面) 座標系|
| その他のデータ型 | geography |地理空間データ型　球体地球座標系のデータ|
| その他のデータ型 | table |テーブル|

https://docs.microsoft.com/ja-jp/sql/t-sql/data-types/data-types-transact-sql?view=sql-server-ver15

# 3.Snowflakeのデータ型
こちらもSnowflakeドキュメントに記載されているデータ型を表にしてみたものになります。
SQLServerに比べるとすっきりしてるようにも見えますが、
たくさんのデータ型に対応できるようになっているみたいですね。

| カテゴリ | 型 | 注意 |
|:------------|:------------|:------------|
| 数値データ型 | NUMBER |デフォルトの精度とスケールは(38,0)です。|
| 数値データ型 | DECIMAL |NUMBERと同義語です。|
| 数値データ型 | NUMERIC |NUMBERと同義語です。|
| 数値データ型 | INT,INTEGER,BIGINT,SMALLINT |精度とスケールを指定できないことを除いて、 NUMBER と同義語です。|
| 数値データ型 | FLOAT,FLOAT4,FLOAT8 ||
| 数値データ型 | DOUBLE |FLOATと同義語です。|
| 数値データ型 | DOUBLE PRECISION |FLOATと同義語です。|
| 数値データ型 | REAL ||
| 文字列およびバイナリデータ型 | VARCHAR |デフォルト（および最大）は、16,777,216バイトです。|
| 文字列およびバイナリデータ型 | CHAR,CHARACTER |デフォルトの長さが VARCHAR（1）を除き、 VARCHAR と同義語です。|
| 文字列およびバイナリデータ型 | STRING |VARCHARと同義語です。|
| 文字列およびバイナリデータ型 | TEXT |VARCHARと同義語です。|
| 文字列およびバイナリデータ型 | BINARY ||
| 文字列およびバイナリデータ型 | VARBINARY|BINARYと同義語です。|
| 論理データ型 | BOOLEAN ||
| 日付と時刻のデータ型 | DATE ||
| 日付と時刻のデータ型 | DATETIME |TIMESTAMP_NTZのエイリアス|
| 日付と時刻のデータ型 | TIME ||
| 日付と時刻のデータ型 | TIMESTAMP |TIMESTAMPバリエーションの1つのエイリアスです。(デフォルトはTIMESTAMP_NTZ)|
| 日付と時刻のデータ型 | TIMESTAMP_LTZ |ローカルタイムゾーンのあるTIMESTAMPです。タイムゾーンが指定されている場合、保存されません。|
| 日付と時刻のデータ型 | TIMESTAMP_NTZ |タイムゾーンのないTIMESTAMPです。タイムゾーンが指定されている場合、保存されません。|
| 日付と時刻のデータ型 | TIMESTAMP_TZ |タイムゾーンのあるTIMESTAMPです。|
| 半構造化データ型 | VARIANT ||
| 半構造化データ型 | OBJECT ||
| 半構造化データ型 | ARRAY ||
| 地理空間データ型 | GEOGRAPHY ||

https://docs.snowflake.com/ja/sql-reference/intro-summary-data-types.html

# 4.データ型変換

SQLServerからSnowflakeに置き換える際のデータ型変換は以下のようになります。
業務で実際変換を行ったものを表に起こしました。
それ以外のものは空白にしております。

| SQLserverのデータ型 | Snowflakeのデータ型 |
|:------------|:------------|
| bigint | NUMBER |
| numeric | NUMBER |
| bit | NUMERIC |
| smallint |  |
| tinyint | NUMBER |
| smallmoney | DOUBLE |
| int | INT |
| tinyint | INT |
| money | VARCHAR |
| float | FLOAT |
| real | REAL |
| date | DATE |
| datetimeoffset | DATETIME |
| datetime2 | DATETIME |
| smalldatetime | DATETIME |
| datetime | DATETIME |
| time | TIME |
| char | VARCHAR |
| varchar | VARCHAR |
| text | VARCHAR |
| nchar | VARCHAR |
| nvarchar | VARCHAR |
| ntext | VARCHAR |
| binary | VARCHAR |
| varbinary | VARCHAR |
| image | VARCHAR |
| cursor ||
| rowversion ||
| hierarchyid ||
| uniqueidentifier ||
| sql_variant ||
| xml ||
| geometry ||
| geography ||
| table ||

※このデータ型はこれに変換しました！等のご意見もお待ちしております。

# おまけ.SQLServerのスタイル(style)から書き換え

SQLServerからSnowflakeへのスクリプトの変換はデータ型だけではなく、
AzureやSQLServerではおなじみ？(Azureはあまり触ったことないので汗)
のスタイル(style)にも注意が必要です。

https://learn.microsoft.com/ja-jp/sql/t-sql/functions/cast-and-convert-transact-sql?redirectedfrom=MSDN&view=sql-server-ver16

この記事を作成するまでにモノは知っていたのですが、名称は初めて知りました。

日本でメジャーに扱っているのはISOと日本のstyleではないでしょうか。※上記事参照

```sql:SQLServerでのCONVERT関数例文.sql
SELECT CONVERT(nvarchar,GETDATE(),111) AS '111'
      ,CONVERT(nvarchar,GETDATE(),11)  AS '11'
      ,CONVERT(nvarchar,GETDATE(),112) AS '112'
      ,CONVERT(nvarchar,GETDATE(),12)  AS '12'

111         11		    112		    12
-----------------------------------------------------
2023/01/19	23/01/19	20230119	230119
```
ただ、これを直接Snowflakeに実装すると
![convert_error.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2992046/7f8192cf-34ed-bea9-b6aa-1c7958e7b419.png)
案の定ですがエラーになってしまいます。

Snowflakeではstyleは無効になってしまうので、
どのように表示させたいか明示的にする必要があります。
また、CONVERTもこのままだと通らないのでSnowflake用に構文を書き換える必要があります。
SnowflakeにはCONVERTとデータ型が合体した関数が存在します！
その名も変換関数です(意味変わらんやん・・・)

https://docs.snowflake.com/ja/sql-reference/functions-conversion.html

今回取得した日付をVARCHAR型にしたいので上記事からTO_VARCHARを使います。
また、列名では''(シングルクォーテーション)では通らないので
””(ダブルクォーテーション)で囲ってあげます。
Snowflake用に書き換えると以下のようになります。


```sql:Snowflakeでの変換関数例文.sql
SELECT 
--TO_VARCHAR( <date_or_time_expr> [, '<format>' ] )
to_varchar(getdate(),'yyyy/mm/dd') as "111",
to_varchar(getdate(),'yy/mm/dd') as "11",
to_varchar(getdate(),'yyyymmdd') as "112",
to_varchar(getdate(),'yymmdd') as "12";
```
Snowflake環境で実行すると・・・
![convert_success.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2992046/0b5fb144-f166-3eea-81fb-8b3f8fd6abdc.png)

無事出力できました！

識別子の要件についてはSnowflakeのドキュメントに詳しく記載されています。

https://docs.snowflake.com/ja/sql-reference/identifiers-syntax.html

# おわりに

今回はSQLServerとSnowflakeを同時期に触り始めときにSQLと仲良くし始めた私が
いっぱい躓いたなと感じた部分だったので文字に起こしてみました。
Snowflakeのドキュメント、かなり詳しく記載されているのでSnowflakeでわからない！があればまずドキュメントで調べてみることをお勧めします。

https://docs.snowflake.com/ja/index.html