- PR -

ある条件順に、日付の終了日をしていしていく方法?

1
投稿者投稿内容
あきこ
会議室デビュー日: 2008/03/07
投稿数: 12
投稿日時: 2008-06-27 12:51
いつも参考にさせていただいております、ありがとうございます。


このような表があるとします。

コード:

hNO | StrDate | EndDate
-------------------
1 | 2008/6/1 |
3 | 2008/6/15 |
2 | 2008/7/2 |
4 | 2008/7/16 |



これを、下記のように、
StrDateで並べ替えて、連番をhNOに再付番し、
かつ、EndDateは、次の順番のレコードのStrDateの前日にしたいと考えています。
(最後の列はNul)

コード:

hNO | StrDate | EndDate
-------------------
1 | 2008/6/1 | 2008/6/14
2 | 2008/6/15 | 2008/7/1
3 | 2008/7/2 | 2008/7/15
4 | 2008/7/16 |



そこで、まずひとつずつ処理してみました。

--日付による連番設定(自己結合)
update a set
hNo = (select count(b.strdate)+1 from t_TownHead b where b.strdate < a.strdate)
from T_TownHead a

とし、連番にすることはできました。

同様に、
--終了日設定
update a set
endDate = (select dateadd(day,-1,b.strdate) from t_TownHead b where b.strdate < a.strdate)
from T_TownHead a

としてみたのですが、エラーが発生し、できませんでした。

エラー内容:
 サブクエリは複数の値を返しました。
 サブクエリが =、!=、<、<=、>、>= の後に続く場合や、
 サブクエリが 1 つの式として使われる場合は複数の値は許可されません。

上記と同様に処理しているので、複数の値が返されるとは思えないのですが・・・

ご教授おねがいいたします。

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-06-27 13:09 ]

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-06-27 13:09 ]
くまっち
大ベテラン
会議室デビュー日: 2008/01/18
投稿数: 169
お住まい・勤務地: 茨城県のどこか。
投稿日時: 2008-06-27 13:35
初めに、使用してるDBMSとバージョンは記述した方がいいですよ。

同様?同じではないですよね。
グループ関数(count)により、集計された結果:単一行。
日付関数(dateadd)により、計算された結果:複数行の可能性も有り。

そして、抽出条件も「小なり」ではなく「大なり」にしないと
求めている答えが出ないと思います。

まずはサブクエリ部分だけ実行して、求めている値が取得出来るか
試してみてはどうでしょうか。

あえて答えは書きません。まずはSQLを理解出来るよう考えてください。
それでも駄目なら、駄目だった理由も添えて再度質問してください。
あきこ
会議室デビュー日: 2008/03/07
投稿数: 12
投稿日時: 2008-06-27 14:44
くまっち様、ご返信ありがとうございます。

バージョン記載、忘れまして、申し訳ありません。
SQLServer2005Express です。

「同様」と申しましたのは、
サブクエリー部分の、
「同じく自己結合方法で、同じwhere句で条件指定をつけたレコード」
と考えていましたので、このように記載しました。
が、これではいけないのですね。

ご指摘くださった、
−−−−
 グループ関数(count)により、集計された結果:単一行。
 日付関数(dateadd)により、計算された結果:複数行の可能性も有り。
−−−−
の部分を見て、考えが浅はかだったことが分かりました。
このwhere句は、Count関数を使用しているからこうなのですね。
今やっと、はっきりこのwhere句のことが分かりました。

サブクエリ部分だけの実行も、この質問を投稿する前に行おうとしたのですが、
サブクエリ部分のみ、となると、
−−−−
 select dateadd(day,-1,b.strdate) from t_TownHead b where b.strdate < a.strdate
−−−−
この部分を、これだけでどうやって実現させればいいのか、修正方法が分からず、実行しませんでした。(where句のaテーブルの部分が?でした。)
連番設定で正常に処理できたので、それと同様の流れで処理するからできるだろうと考えておりました。

となると、終了日を設定するためには、
私の頭ではループでまわして1レコードずつ処理することしか思い浮かびませんので、
再度HP等で調べたいと思います。

ご指摘ありがとうございました!
あきこ
会議室デビュー日: 2008/03/07
投稿数: 12
投稿日時: 2008-06-27 15:08
ループにせず、
--終了日設定
update a set
endDate = (select dateadd(day,-1,min(b.strdate)) from t_TownHead b where a.strdate < b.strdate)
from T_TownHead a

で、希望の処理ができました!

くまっち様、ありがとうございました!
1

スキルアップ/キャリアアップ(JOB@IT)