月名称の変換表を取得する

月名称の英略称(Jan, Feb, …)と数値の月の変換表を物理テーブルを作成せずに取得する方法です。全部で4種類作ってみました。尚、利用したバージョンは SQLServer 2019 です。

リテラル値の列挙による変換表

オーソドックスにリテラル値を UNION ALL で列挙した変換表です。せめてVIEWにして利用しないとアレですが。

WITH MONTH_TABLE( MONTH_NAME, MONTH_NUMBER ) AS (
  SELECT N'Jan',  1 UNION ALL
  SELECT N'Feb',  2 UNION ALL
  SELECT N'Mar',  3 UNION ALL
  SELECT N'Apr',  4 UNION ALL
  SELECT N'May',  5 UNION ALL
  SELECT N'Jun',  6 UNION ALL
  SELECT N'Jul',  7 UNION ALL
  SELECT N'Aug',  8 UNION ALL
  SELECT N'Sep',  9 UNION ALL
  SELECT N'Oct', 10 UNION ALL
  SELECT N'Nov', 11 UNION ALL
  SELECT N'Dec', 12
)
SELECT MONTH_NAME
     , MONTH_NUMBER
FROM MONTH_TABLE;

テーブル値コンストラクターによる変換表

同じくリテラル値の列挙ではあるのですが、テーブル値コンストラクタを利用して若干スマートに書いてみます。

SELECT MONTH_NAME
     , MONTH_NUMBER
FROM ( VALUES
  (N'Jan', 1),(N'Feb', 2),(N'Mar', 3),(N'Apr',  4),(N'May',  5),(N'Jun', 6),
  (N'Jul', 7),(N'Aug', 8),(N'Sep', 9),(N'Oct', 10),(N'Nov', 11),(N'Dec', 12)
) MONTH_TABLE( MONTH_NAME,MONTH_NUMBER );

再帰SQLとFORMAT関数による変換表

FORMAT関数を利用すれば月名称の略称は取得できます。これを利用して1~12の数値を再帰SQLで生成して変換表を作成します。

WITH MONTH_TABLE AS (
  SELECT 1 AS MONTH_NUMBER
  UNION ALL 
  SELECT MONTH_NUMBER + 1 FROM MONTH_TABLE 
  WHERE MONTH_TABLE.MONTH_NUMBER < 12
) 
SELECT FORMAT(DATEFROMPARTS(2000,MONTH_NUMBER,1),'MMM','en-US') MONTH_NAME
     , MONTH_NUMBER
  FROM MONTH_TABLE;

システムカタログ SYSLANGUAGES の値を利用した変換表

SQLServer のシステムカタログ SYSLANGUAGES には言語毎の月名称の略称を持っています。

SYSLANGUAGES

ただ、この値はコンマ区切りの文字列として保持されていますので、STRING_SPLIT 関数を利用してテーブル値として取得してみます。月の数値は、ROW_NUMBER で新たに採番します。

SELECT T.VALUE MONTH_NAME
     , ROW_NUMBER() OVER (ORDER BY (SELECT 1)) MONTH_NUMBER
  FROM STRING_SPLIT((SELECT SHORTMONTHS
                       FROM SYS.SYSLANGUAGES
                      WHERE ALIAS = 'British English')
                   , ',') AS T;

取得結果

いずれのSQLを実行しても同じ結果が得られます。VIEW にしておけば、他のテーブルとの結合にも使いやすくなると思います。

実行結果