dポイントプレゼントキャンペーン実施中!

SQL2005でクエリを走らせて調査したいので教えてください
●取引データ●
------------------------------
企業 取引開始日 取引終了日
------------------------------
A   20110610   20110612
A    20110701   20110710
B   20110401   20110403
B   20110408   20110421
B   20110701   20110701

とデータがあった場合、今回の取引開始日と前回の取引終了日を比較して3週間以内かどうかの調査をしたいのですが、クエリで一発で出す方法がないでしょうか?
検索して調査した結果、相関サブクエリで行えるのでは???と思い試しましたが構文がイケてないようで、思ったように出てきません。
相関サブクエリの意味があまり理解できないので助言をお願いいたします。

件数が多いので、とりあえずA企業だけでのクエリで走るかどうか調査したいので企業を限定しました

select d1.取引開始日, d1.取引終了日
from 取引データ as d1, 取引データ as d2
where
d1.企業 = 'A'
and
d2. 取引開始日 = (select min(d3.取引開始日)
                from 取引データ as d3
where d3.取引開始日 > d1.取引終了日 + '21')

出力したい結果ですが

---------------------------------------------------
企業 取引開始日 取引終了日  ★経過日  ★3週間以上
---------------------------------------------------
A   20110610    20110612
A   20110701   20110710    18
B   20110401   20110403    
B   20110408   20110421     5
B   20110701   20110701    70        ○

対処法をご教示いただきますようどうぞ宜しくお願いいたします。

A 回答 (4件)

No.1です。



インラインビューには別名をつけないといけないということかもしれません。

select
企業
,取引開始日
,取引終了日
,取引開始日 - 前回取引終了日 as 経過日
,case when (取引開始日 - 前回取引終了日) > 21 then '○' else null end as "3週間以上"
from
(select
企業
,取引開始日
,取引終了日
,(select max(取引終了日) from 取引データ B
where b.企業 = a.企業 and b.取引終了日 < a.取引開始日) as 前回取引終了日
from 取引データ A) as 取引データ;

などとして試してみてください。
    • good
    • 0

SQLを考える場合は理論を組み立てないと、


「たまたまできた」に期待するしかなくなります。

【理論】
1、自レコードの取引開始日より小さい取引終了日を
 持つデータ集合を作る。
2、上記データ集合中直近、つまり取引終了日の
 最大値を求める。
3、自レコードの取引開始日とデータ集合の
 取引終了日の最大値との差が経過日数である。

とりあえず3週間経過かどうかは別として、経過日数を
求めるSQLは次のようになるかと思います。

SELECT A.企業,A.取引開始日,A.取引終了日,
CASE
  WHEN Max(B.取引終了日) IS NULL THEN NULL
  ELSE DATEDIFF(day,Max(B.取引終了日),A.取引開始日)
END AS 経過日数
FROM 取引データ A LEFT OUTER JOIN 取引データ B
ON A.企業=B.企業 AND A.取引開始日>B.取引終了日
GROUP BY A.企業,A.取引開始日,A.取引終了日

インデントに漢字空白を使っています。コピペしただけでは
エラーになるので、漢字空白を半角にしてください。
    • good
    • 0
この回答へのお礼

くわしい説明をありがとうございます。

A企業内での取引開始日と前回取引終了日を比較していき、経過日数を右へ出したいのですが、イマイチループ処理がわかっていませんでした。

クエリを走らせたのですが、思ったような数字がでませんでした。
一覧はそのままデータとして表示しておきたいのですが、穴空きになってしまいます。

お礼日時:2011/07/28 15:21

確認できる環境が手元にないのでミスってるかもですが、


こんな感じでいけませんかね?

select d1.企業, d1.取引開始日, d1.取引終了日,
datediff(day, d1.取引開始日, d1.取引終了日) as ★経過日,
case when
select top 1 d2.取引終了日 from 取引データ as d2
where d1.企業 = d2.企業
and d1.取引開始日 > dateadd(week, 3, d2.取引終了日)
is null then '' else '○'
end as ★3週間以上
from 取引データ as d1
order by d1.企業, d1.取引開始日

サブクエリ部分はcountにして0件かどうかを判断してもいいですが、
たぶんこのほうがレスポンスはいいはず。
    • good
    • 0
この回答へのお礼

早々にありがとうございました。

2点エラーが出ます。

メッセージ156 レベル15 状態1
キーワード'select'付近に不適切な構文があります

select top 1 d2.取引終了日 from ・・・
このtop 1 ってのを top01() top1() にしてみましたが駄目でした。


メッセージ156 レベル15 状態1
キーワード'is'付近に不適切な構文があります。

is null then '' else '○' ここに問題ありでしょうか・・・。

お礼日時:2011/07/28 13:45

サブクエリで前回の取引終了日を取得して比較すればいいのではないでしょうか。


たとえばこんな感じで。

select
企業
,取引開始日
,取引終了日
,取引開始日 - 前回取引終了日 as 経過日
,case when (取引開始日 - 前回取引終了日) > 21 then '○' else null end as "3週間以上"
from
(select
企業
,取引開始日
,取引終了日
,(select max(取引終了日) from 取引データ B
where b.企業 = a.企業 and b.取引終了日 < a.取引開始日) as 前回取引終了日
from 取引データ A);

動作確認はしていません・・・
    • good
    • 0
この回答へのお礼

早々にありがとうございました。

ところが、最終行のところで

from 取引データ A);

でエラーが出ます。
メッセージ102 レベル15 状態1
')'付近に不適切な構文があります。

となってしまいます。

お礼日時:2011/07/28 13:11

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す