2

私はこのテーブルを持っています:

create table #tbl
 (
    dt datetime
 )

 insert into #tbl values ('2013-01-01 00:00:00')
 insert into #tbl values ('2013-02-01 00:00:00')
 insert into #tbl values ('2013-02-02 00:00:00')
 insert into #tbl values ('2013-03-01 00:00:00')

各月の開始日と終了日を取得する必要があります。つまり、これは期待される結果です。

[start]                    [end]
 2013-01-01 00:00:00.000    2013-01-31 23:59:59.997
 2013-02-01 00:00:00.000    2013-02-28 23:59:59.997
 2013-03-01 00:00:00.000    2013-03-31 23:59:59.997

どうすればいいのかわからない。助けてください。

select
 dateadd(mm, datediff(mm, 0, ???, 0),
 dateadd(ms, -3, dateadd(mm, datediff(m, 0, ??? + 1, 0))

MS SQL Server 2008 を使用しています。

4

3 に答える 3

1
;with dm as (
    select distinct rm = datediff(mm, 0, dt)
    from #tbl t
)
select ms.[start], me.[end]
from dm
    cross apply (select dateadd(mm, dm.rm, 0)) ms([start])
    cross apply (select dateadd(ms, -3, dateadd(month, 1, ms.Value))) me([end])

ロジックは次のとおりです。rmテーブル内の各日付について、その日付から経過した月数を見つけます0(つまり、1900 年 1 月から 1900 年cast(0 as datetime)1 月 1 日まで)。重複を避けるためdistinctに使用されます:

select distinct rm = datediff(mm, 0, dt)
from #tbl t

上記のステートメントは、 という名前の CTE にラップされdmます。dm次に、式を使用して対応する月の始まりの日付を計算する行ごとにdateadd(mm, dm.rm, 0)(1900 年 1 月から経過した月数を追加すると、元の日付がその途中にあったとしても、月の始まりが得られます)。その値は だけでなく、月末日の計算にもcross apply使用されるため、構文を使用してクエリに追加されます。select終了日は、開始日に 1 か月を加算し、3 ミリ秒を引いて計算されます (終了日が翌月の開始日とならないようにするため)。

于 2013-08-16T22:05:59.390 に答える