1

Informix 11.70.TC4:

ユーザーが「1」、「2」、または「3」のいずれを選択したかに応じて、日付 ​​(pk_date) を検索し、別の日付 (plus1、plus2、または plus3_months) をクライアントに返すために使用される SQL ディメンション テーブルがあります。 "。

テーブル スキーマは次のとおりです。

TABLE date_lookup
(
    pk_date DATE,
    plus1_months DATE,
    plus2_months DATE,
    plus3_months DATE
);

UNIQUE INDEX on date_lookup(pk_date);

2012 年 1 月 28 日から 2014 年 3 月 31 日までの日付を含むロード ファイル (パイプ区切り) があります。

次に、ロード ファイルの例を示します。

01-28-2012|02-28-2012|03-28-2012|04-28-2012|
01-29-2012|02-29-2012|03-29-2012|04-29-2012|
01-30-2012|02-29-2012|03-30-2012|04-30-2012|
01-31-2012|02-29-2012|03-31-2012|04-30-2012|
...
03-31-2014|04-30-2014|05-31-2014|06-30-2014|

................................................................... ...................................................

編集: 11.70.TC5を使用したジョナサン卿の SQL ステートメントが機能しました!DATE(pk_date + n UNITS MONTH

ここに画像の説明を入力

2012 年 1 月 28 日から 2020 年 12 月 31 日までの pk_date と、plus1、plus2、および plus3_months NULL を含むロード ファイルを生成しました。これを date_lookup テーブルにロードし、以下の update ステートメントを実行しました。

UPDATE date_lookup
   SET plus1_months = DATE(pk_date + 1 UNITS MONTH),
       plus2_months = DATE(pk_date + 2 UNITS MONTH),
       plus3_months = DATE(pk_date + 3 UNITS MONTH);

どうやら、DATE() は pk_date を DATETIME に変換し、TC5 の新しいアルゴリズムで計算を行い、結果を DATE 形式で返すことができたようです!

................................................................... ...................................................

このディメンション テーブルのルールは次のとおりです。

  • pk_date の月が 31 日で、plus1、plus2、または plus3_months が 28、29、または 30 日しかない場合、plus1、plus2、または plus3 はその月の最終日に等しくなります。
  • pk_date がその月に 30 日あり、plus1、plus2、または plus3 がその月に 28 日または 29 日ある場合、それらをそれらの月の最後の有効な日付に等しくします。
  • 他のすべての日付は、翌月の同じ日に当たります。

私の質問は次のとおりです。上記のルールに従って、2014 年 3 月 31 日以降の pk_dates を自動的に生成する最良の方法は何ですか? SQL スクリプト、「sed」、C プログラムでこれを実現できますか?

編集:私sedはすでに 2 年以上のデータを持っているので、このデータの後に残りをモデル化できるのでしょうか、それともツールのようなawk方が良いのでしょうか?

4

2 に答える 2

1

最善の方法は、11.70.TC5 (32 ビット Windows の場合。通常は 11.70.xC5 以降) にアップグレードし、次のような式を使用することです。

SELECT DATE(given_date + n UNITS MONTH)
  FROM Wherever
...

DATETIME コードは 11.70.xC4 と 11.70.xC5 の間で変更され、日付が説明どおりであり、+ n UNITS MONTHまたは同等の表記を使用する場合に、概要を示したルールに従って日付を生成します。

これにより、テーブルがまったく不要になります。ただし、明らかに、すべてのクライアントも 11.70.xC5 上にある必要があります。

おそらく、開発用マシンを 11.70.xC5 に更新してから、このプロパティを使用して開発用マシンでテーブルのデータを生成し、そのデータをクライアントに配布できます。

少なくとも誰かを 11.70.xC5 にアップグレードできない場合は、Perl スクリプトの提案を検討してください。

于 2012-07-16T22:09:07.353 に答える
1

SQLでできますか?おそらくですが、それは耐え難いでしょう。Cについても同様で、sedについては「いいえ」が答えだと思います。

ただし、数十行の perl で必要なものが生成されるようです。

#!/usr/bin/perl

use strict;
use warnings;
use DateTime;

my @dates;

# parse arguments
while (my $datep = shift){
    my ($m,$d,$y) = split('-', $datep);
    push(@dates, DateTime->new(year => $y, month => $m, day => $d))
        || die "Cannot parse date $!\n";
}

open(STDOUT, ">", "output.unl") || die "Unable to create output file.";
my ($date, $end) = @dates;
while( $date < $end ){
    my @row = ($date->mdy('-')); # start with pk_date
    for my $mth ( qw[ 1 2 3 ] ){
        my $fut_d = $date->clone->add(months => $mth);
        until   (
                    ($fut_d->month == $date->month + $mth
                       && $fut_d->year == $date->year) ||
                    ($fut_d->month == $date->month + $mth - 12
                       && $fut_d->year > $date->year)
                ){
                    $fut_d->subtract(days => 1); # step back until criteria met
                }
        push(@row, $fut_d->mdy('-'));
    }
    print STDOUT join("|", @row, "\n");
    $date->add(days => 1);
}

これを futuredates.pl として保存し、次のchmod +xように実行します。

$ futuredates.pl 04-01-2014 12-31-2020

それは私にとってはうまくいくようです。

于 2012-07-16T04:23:48.327 に答える