1

先月完了したとスタンプされたすべてのレコードの数を返そうとしています。列名の実際の日時フィールド。これは、先月の記録が完了していることを確認する必要があるのと同じフィールドです。

これは私が持っているものです

SELECT count(*) 
FROM PhoneCall AS p WITH (nolock) 
WHERE   ( p.actualend >= CAST(CONVERT(varchar(8), DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1), DATEADD(mm, - 1, GETDATE())), 1) AS datetime)) 
  AND ( p.actualend <= CAST(CONVERT(varchar(8), DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)), 1) AS datetime))

このコードでは、わずかに高い結果が得られます (合計結果は 847 です)。

しかし、このコードを実行すると

SELECT count(*) 
FROM PhoneCall AS p WITH (nolock) 
WHERE p.actualend BETWEEN '03/01/2013 00:00:00' AND '03/31/2013 23:59:59' 

合計 843 レコードを取得します。最初のクエリを修正して、両方のクエリで同じ合計を取得するにはどうすればよいですか?

ありがとう

4

2 に答える 2

1

最初のクエリでは、最終日に完全にスタンプされたすべてのレコードが取得されません。これは、最終日の計算で午前 12:00:00 の正しい日付が返されるためです。時刻の部分を 11:59:59 PM にします。

クエリのロジックをテストするために、select ステートメントを実行して、前月の最初と最後の日の計算結果を確認しました。

select CAST(CONVERT(varchar(8), DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1), DATEADD(mm, - 1, GETDATE())), 1) AS datetime)
select CAST(CONVERT(varchar(8), DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)), 1) AS datetime)

結果は2013-04-01 00:00:00.0002013-04-30 00:00:00.000でした。(2013 年 5 月 7 日現在の日付に基づく)

前月の末日ではなく当月の初日を計算し、<比較ではなく比較を行うことをお勧めします<=。そうすれば、記録が 1 日の最後の数ミリ秒で完全にスタンプされた場合にどうなるかを処理する必要はありません。

月末の計算に 1 日を追加して、以下の元のクエリを変更しました。つまり、現在の月の最初の日を効果的に計算します。次に、比較演算子を1の代わりにに変更しました<=。おそらくこの計算を改善することができますが、これはロジックの例を示すための迅速かつ簡単な方法にすぎません。

SELECT count(*) 
FROM PhoneCall AS p WITH (nolock) 
WHERE ( p.actualend >= CAST(CONVERT(varchar(8), DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1), DATEADD(mm, - 1, GETDATE())), 1) AS datetime))
  AND ( p.actualend < CAST(CONVERT(varchar(8), DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0)), 1) AS datetime) + 1)
于 2013-05-07T22:27:39.607 に答える
1

アダムは正しい答えを持っています。ただ、分かりやすくするためには、こういう形でもいいのではないかと思います。

2 つの日付の間でデータを選択する要点は、Adam の 2 番目のクエリにあるこのロジックを使用することです。

where YourField >= @StartDate
and YourField < the day after @EndDate

アプリケーション (.net、php、coldfusion など) からこのクエリを呼び出す場合は、アプリケーションでこれらの変数を作成し、パラメーターとして送信する方が簡単な場合があります。それ以外の場合は、次のようなことをしたいかもしれません:

  declare @EndDate as datetime;
  declare @StartDate as datetime;

  set @EndDate = CAST(CONVERT(varchar(8)
  , DATEADD(dd, - (DAY(DATEADD(mm, 1, GETDATE())) - 1)
 , DATEADD(mm, 0, GETDATE())), 1) AS datetime);

 set @StartDate = DateAdd(month, -1, @EndDate);

 SELECT count(*) 
 FROM lassqls1.CareCredit_MSCRM.dbo.PhoneCall AS p WITH (nolock) 
 WHERE p.actualend >= @StartDate
 and p.actualend < @EndDate
于 2013-05-07T22:45:39.350 に答える