SQLの日付
私はそれを次のように考えます:サーバーは実際には特定の日の参照として日付を保存します。それがどのように行われるかはあなたの関心事ではありません。このような日付列にデータを格納したり、そのような日付列からデータを読み取ったりする場合、サーバーは特定のカレンダーを使用してその日付を表します。これは慣例によりグレゴリオ暦です。私が言おうとしているのは、保存された値がグレゴリオ暦であるとは思わないということです。むしろ、移管された日付はグレゴリオ暦であると考えたいと思います。
したがって、私の意見では、最善の解決策は、その事実を受け入れ、アプリケーション側でグレゴリオ暦とイスラム暦の間で変換することです。そうすれば、通常のbetween
チェックを使用できます。
数字で構成された文字列
ロケールに依存する変換が複雑すぎるため、またはイスラム暦とグロゴリアンの間のマッピングが一意でないか事前に不明であるためにこれが不可能な場合は、日付を別の形式で保存する必要があります。私の頭に浮かぶ可能性のある形式は、数字を意味する文字をvarchar
含む形式の文字列を含むものです。YYYY-MM-DD
このスキームにより、文字列がそれらが表す日付のように比較されることが保証されるため、文字列で引き続き使用できbetween
ます。ただし、これらの文字列をスペルアウトされた日付に戻すのは難しいでしょう。
1つ以上の数値列
したがって、実際には3つの列を使用することをお勧めします。各列には日付を示す数値が含まれています。次に、を使用10000*year + 100*month + day_of_month
して、比較やに使用できる、毎日1つの数値を取得できますbetween
。一方、ELT
クエリでこの関数を使用すると、その月の数値を名前に戻すことができます。パフォーマンスが問題になる場合は、1つの数値だけを保存し、選択時にそれを部分に分割する方がよい場合があります。グレゴリオ暦では、これは次のようになります。
CREATE TABLE tableName (myDate DECIMAL(8));
SELECT myDate DIV 10000 AS year,
ELT((myDate DIV 100) MOD 100, "Jan", "Feb", …) AS month,
myDate MOD 100 AS day_of_month
FROM tableName
WHERE myDate BETWEN 20121021 AND 20121023;
互換性と利便性
単一のテキストの日付列を期待するコードとの読み取り専用の互換性を維持する必要がある場合は、を使用しVIEW
てそれを提供できます。たとえば、ドイツ語のグレゴリオ暦の場合、次のDD. MMMM YYYY
ようなコードを使用できます。
CREATE VIEW compatibleName AS
SELECT CONCAT(myDate MOD 100, ". ",
ELT((myDate DIV 100) MOD 100, "Januar", "Februar", …), ". ",
myDate DIV 10000) as dateString,
* -- or explicitely name other columns needed for compatibility
FROM tableName
文字列のデコード
文字列形式を使用した別のアプリケーションによる読み取り/書き込みアクセスが必要な場合は、それらの文字列を自分で解析する必要があります。これはSQLレベルで実行できます。便利なツールはSUBSTRING_INDEX
、文字列をフィールドに分割しFIELD
、月の名前を数値に変換することです。データベースにトリガーを追加すると、文字列が常に有効な形式になり、この方法で分解できるようになります。この質問では、トリガーを使用してそのようなチェックを実施する方法について詳しく説明します。