再帰的に?データを取得する

解決


ソロ  2002-09-03 03:31:17  No: 1423

いつもお世話になっております。
ソロです。

あるデータをDBより取得し、配列に入れたいのですが、
データの格納方法に行き詰まってしまいました。

DBは、

カラムA
-------
001
002
003
004
005

と単純なのですが、
欲しい2次元配列情報としては、

D[i,j] = [001,002] [001,003] [001,004] [001,005]
D[i,j] = [002,003] [002,004] [002,005] [002,001]
D[i,j] = [003,004] [003,005] [003,001] [003,002]
D[i,j] = [004,005] [004,001] [001,002] [001,003]
D[i,j] = [005,001] [005,002] [005,003] [001,004]

という形で、006,007・・・とデータが増えていくことも考慮せねばなりません。
どういったロジックを作れば上記のような2次元配列を作れのか
教えていただきたいです。

よろしくお願いします。

あと、自ら質問を立てて解決した場合に
解決済みにするにはどうしたらいいのでしょうか。


hatena  2002-09-03 07:27:03  No: 1424

具体的なようで、何がしたいのかあいまいで、意味不明です。
元データの仕様や、欲しい配列の仕様をもう少し具体的に書いてもらわないと。

>DBは、
>
>カラムA
>-------
>001
>002
>003
>004
>005

このフィールドのデータ型は、数値?、文字列?、それともインデックスを
表しているだけ?。

>欲しい2次元配列情報としては、
>
>D[i,j] = [001,002] [001,003] [001,004] [001,005]
>D[i,j] = [002,003] [002,004] [002,005] [002,001]
>D[i,j] = [003,004] [003,005] [003,001] [003,002]
>D[i,j] = [004,005] [004,001] [001,002] [001,003]
>D[i,j] = [005,001] [005,002] [005,003] [001,004]

001 が要素で 2×4の2次元配列が、5つあるということ?
それとも、[001,002]が要素で、5×4の2次元配列配列?
[001,002]はレコード型?
はたまた、D[i,j]というが、2次元配列の要素で
その中身が[001,002] [001,003] [001,004] [001,005]なの?

なんか全部はずしているような気もするし???

>あと、自ら質問を立てて解決した場合に
>解決済みにするにはどうしたらいいのでしょうか。

発言欄のすぐ上にあるチェックボックスをチェックします。


hatena  2002-09-03 20:00:38  No: 1425

補足です。

細かい仕様はさておき、ロジックとしては、
データが増えていくことも考慮すると言うことなので、
「多次元動的配列」を使うことになると思います。
値のセットは、For文を入れ子にすれば、簡単にできます。
ヘルプで「多次元動的配列」を検索すると、例が載ってますので、
参考にしてみて下さい。


ソロ  2002-09-03 20:08:42  No: 1426

すいません、うまく説明できてなかったです。。(^^;)

>このフィールドのデータ型は、数値?、文字列?、それともインデックスを
>表しているだけ?。

文字列です。

ある物流システムで運送会社の運送実績の一覧(1ヶ月単位)を
Excel出力しようとしています。

東京・名古屋・大阪・広島・福岡の5都市にまたがってまして、
それぞれの都市からそれぞれの都市に向かって運送トラックなどが
走っています。

(8月分)
            1  2  3  4  5  6  7  ・  ・  ・  31  ←日付
東京発      
  名古屋着  8  9  1  2  7  5  2  ・  ・  ・  17  ←個数
  大阪着    1  9  1  7  4  5  8  ・  ・  ・  22  ←個数
  広島着    8  7  9  3  7  6  1  ・  ・  ・  11  ←個数
  福岡着    3  9  1  2  7  5  7  ・  ・  ・  28  ←個数

という感じの表を出力します。
また、名古屋発、大阪発・・・と発地が5つで
それに付随する着地が4つで、発地-着地の組み合わせが合計20通りになり、
そのパラメータをSQLのWERER句に入れてデータを取得したいと思ってます。

(SQL)
SELECT
 運送個数
FROM
 TABLE
WHERE
 発地='東京'
AND
 着地='大阪'
AND
 日付='2002/08/01'

みたいな感じのSQLです。
この発地-着地の組み合わせを効率的に管理するために考えたのが
配列情報として持つという方法だったわけです。
他に良い方法があれば教えて頂きたいです。


hatena  2002-09-03 23:35:20  No: 1427

こんにちは。

なるほど、よくわかりました。
いろいろなやり方が考えられますが、私なりにロジックを考えてみました。
これを参考に自分なりのロジックを考えてみて下さい。

まず、要素に、発地と着地を持つ、5×4の2次元動的配列にすることに
します。

文字列型の配列に、都市名を格納します。
TPoint型に、発地と着地を、都市名配列のインデックスで格納します。
TPoint型の2次元動的配列に、これを格納します。

TPoint は2つのInteger型を持っているので、発地と着地のインデックスを
格納するのに流用しました。独自にレコード型を宣言した方が分かりやすいかも
しれません。

var
  Citys: Array of string;
  A: Array of Array of TPoint;
  C, I, J :Integer;
begin
  C := 5; //都市数を設定
  SetLength(Citys, C);
  Citys[0] := '東京';
  Citys[1] := '名古屋';
  Citys[2] := '大阪';
  Citys[3] := '広島';
  Citys[4] := '福岡';

  SetLength(A, C, C-1);

  //配列にセット
  for I := 0 to C - 1 do
    for J := 0 to C - 2 do
      A[I,J] := Point(I, (I + J + 1) Mod C);

  //配列から読み出し
  for I := 0 to C - 1 do
  begin
    for J := 0 to C - 2 do
      Memo1.Lines.Add(Citys[A[I, J].x] + '発,' + Citys[A[I, J].y] + '着');
  //ここで少し手を加えれば、SQL文を作るのは簡単だと思います。
  end;

end;


ソロ  2002-09-04 02:22:58  No: 1428

すいません、遅くなりました。

ありがとうございます。
さっそく試してみます。

今日明日中にはご報告します。  (^^)


ソロ  2002-09-05 01:07:17  No: 1429

お世話になっております、ソロです。

>A[I,J] := Point(I,(I+J+1)Mod C);

のところで、’)’が必要な場所に〜っていうエラーが出てくるんです。(^^;)

あと、TPoint型のレコードは画面上のピクセル位置を定義する型
みたいなのですが、これを今回の件にどう応用するのか分からないです。。


hatena  2002-09-05 06:29:06  No: 1430

>>A[I,J] := Point(I,(I+J+1)Mod C);
>
>のところで、’)’が必要な場所に〜っていうエラーが出てくるんです。(^^;)

おかしいでね。テストプロジェクトを作って、コンパイルが通っているコードを
コピペしてますので、間違いないはずです。
新規プロジェクトにボタンとメモを置いて、ボタンのクリックイベントに、
このコードをコピペして試してみて下さい。

>あと、TPoint型のレコードは画面上のピクセル位置を定義する型
>みたいなのですが、これを今回の件にどう応用するのか分からないです。

本来は、
type 
  TCourse = packed record
  StartID: integer; //発地のインデックス
  EndID: integer;   //着地のインデックス
end;

var
  Citys: Array of string;
  A: Array of Array of TCourse;

とレコード型を宣言して、都市名の配列のインデックスを2つ格納すべきなんで
すが、手抜きをして、既にある TPoint 型で間に合わせようということです。
X座標が、発地インデックス、Y座標が着地インデックスということになります。

ソロさんの最初の質問の中の [001,002] の部分を、TPoint型で代用している
わけです。

>  //配列にセット
>  for I := 0 to C - 1 do
>    for J := 0 to C - 2 do
>      A[I,J] := Point(I, (I + J + 1) Mod C);

の部分は、下記のようなTPoint型の配列を作っています。

 (0,1) (0,2) (0,3) (0,4)
 (1,2) (1,3) (1,4) (1,0)
 (2,3) (2,4) (2,0) (2,1)
 (3,4) (3,0) (3,1) (3,2)
 (4,0) (4,1) (4,2) (4,3)

最初の質問の中の図とほとんど同じですよね。

で、このコードを実行するとメモに、下記のように表示されます。

東京発 名古屋着
東京発 大阪着
東京発 広島着
東京発 福岡着
名古屋発 大阪着
名古屋発 広島着
名古屋発 福岡着
名古屋発 東京着
大阪発 広島着
大阪発 福岡着
大阪発 東京着
大阪発 名古屋着
広島発 福岡着
広島発 東京着
広島発 名古屋着
広島発 大阪着
福岡発 東京着
福岡発 名古屋着
福岡発 大阪着
福岡発 広島着


にしの  2002-09-05 07:34:33  No: 1431

ちょっとDelphiから離れますが…

CREATE TABLE TBL_地名
(
  地名 VARCHAR(50)
);
というテーブルに、
INSERT INTO TBL_地名 (地名) VALUES('東京');
INSERT INTO TBL_地名 (地名) VALUES('名古屋');
INSERT INTO TBL_地名 (地名) VALUES('大阪');
INSERT INTO TBL_地名 (地名) VALUES('広島');
INSERT INTO TBL_地名 (地名) VALUES('福岡');
としておいて、
SELECT A.地名 AS 発地, B.地名 AS 着地 FROM TBL_地名 A, TBL_地名 B
WHERE A.地名 <> B.地名
とすれば、20通りの発地・着地が取れます。
これに対して、日付と個数を外部結合してやれば、期待した表が取れると思うのですが。
データ件数によっては、外部結合では遅くなる場合もあります。


hatena  2002-09-05 19:22:53  No: 1432

にしのさん、こんにちは。

あっ、そうか。データベースを使っているんなら、
SQL を使えば一発ですね。

データベースと言うことなら、テーブル設計としては、
地名テーブルのフィールドは、地名ID, 地名,として、
運送個数のテーブルには、地名 でなく、地名ID を持たせて、
それで結合するようにした方がいいですね。


ソロ  2002-09-05 20:16:43  No: 1433

お世話になっております。ソロです。

>hatenaさん

できました!  v(^^)v
なるほど、Memoを付け加える必要があったのですね。
全然そんな発想が浮かびませんでした。(^^;)

何度も答えていただいて、本当にありがとうございました。<(_  _)>

>にしのさん

やってみてないのであまり胸を張っていえないんですが、
この方法だと20通りの発地・着地情報が取れても
  _______________  
(                              )
  東京→名古屋→大阪→広島→福岡

という順番で確実に取れないような。。。(^^;)
[1,2][1,3][1,4][1,5] の次が
[2,1][2,3][2,4][2,5] という風になりそうな気がするんです。
[2,3][2,4][2,5][2,1] ←こういう感じでできれば最高です。(^^)


ソロ  2002-09-05 20:49:06  No: 1434

一応、解決マークを出しておきます。(^^)


にしの  2002-09-05 22:08:01  No: 1435

順番が必要なら、

SELECT A.ID AS HACCHI_ID, B.ID AS CHAKUCHI_ID
FROM TBL_CHIMEI A, TBL_CHIMEI B
WHERE A.ID <> B.ID
ORDER BY HACCHI_ID, (A.ID<B.ID) DESC, CHAKUCHI_ID

こんな感じでできますね。
あとは工夫次第です。
# DBはPostgresを使用したので、少し変えないとできないかもしれません


ソロ  2002-09-05 22:13:29  No: 1436

>SELECT A.ID AS HACCHI_ID, B.ID AS CHAKUCHI_ID
>FROM TBL_CHIMEI A, TBL_CHIMEI B
>WHERE A.ID <> B.ID
>ORDER BY HACCHI_ID, (A.ID<B.ID) DESC, CHAKUCHI_ID

なるほど、その手がありましたね。(^^)
状況に応じて使い分けるようにします。

ありがとうございました。<(_  _)>


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加