5

私はその年のすべての日付をリストした表を持っています。各行には、毎年ループする1から13までの期間番号も含まれています。これは次のようになります。

|        Date         | Period |
| 2012-12-27 00:00:00 |   12   |
| 2012-12-28 00:00:00 |   12   |
| 2012-12-29 00:00:00 |   13   |
| 2012-12-30 00:00:00 |   13   |
| 2012-12-31 00:00:00 |   13   |
| 2013-01-01 00:00:00 |   13   |
| 2013-01-02 00:00:00 |   13   |
|        . . .        |   13   | 
| 2013-02-10 00:00:00 |   01   |
|        . . .        |   01   | 
| 2013-03-14 00:00:00 |   02   |
|        . . .        |   02   | 
| 2013-05-05 00:00:00 |   03   |

上記のように、期間13は2012年12月29日に始まり、2013年2月9日に終了します。期間13の最初と最後の日付を取得することでこれを解決します。

現在の期間の期間の開始日と終了日を取得するクエリを作成する必要があります。しかし、この例のように、期間が年に2回発生することもあれば、年の間で重複することもあるため、問題が発生しています。

さらにいくつかの例:

getDate()= '2013-02-25 13:45:00'の場合、期間は01であり、開始日と終了日は'2013-02-10000:00:00'および'2013-03-14になります。 00:00:00 '

getDate()= '2013-03-15 00:00:00'の場合、期間は02であり、開始日と終了日は'2013-03-1400:00:00'および'2013-05-05になります。 00:00:00 '

これが理にかなっていることを本当に願っています。明確にする必要がある場合はお知らせください。ご協力いただきありがとうございます :)

4

5 に答える 5

4

SQL Server 2012を使用している場合は、lagまたはleadを使用します。代わりに、相関サブクエリを使用します。

select min(period) as period, MIN(date), MAX(date)
from (select t.*,
             (select min(date) from t t2 where t2.period <> t.period and t2.date > t.date) as nextp
      from t
     ) t
group by nextp

内部サブクエリは、次の期間の日付を取得します。これは、同じ期間のレコードを持つ連続したレコードの場合も同じです。その後、これをグループ化に使用できます。

于 2013-01-04T14:29:12.783 に答える
3

ある期間の開始日と終了日を見つける2つの再帰cte。

with CStart as
(
  select Date,
         Period
  from DateTable
  where Date = cast(getdate() as date)
  union all
  select D.Date,
         D.Period
  from DateTable as D
    inner join CStart
      on dateadd(day, -1, CStart.Date) = D.Date and
         CStart.Period = D.Period
),
CEnd as
(
  select Date,
         Period
  from DateTable
  where Date = cast(getdate() as date)
  union all
  select D.Date,
         D.Period
  from DateTable as D
    inner join CEnd
      on dateadd(day, 1, CEnd.Date) = D.Date and
         CEnd.Period = D.Period
),
CPeriod as
(
  select Period
  from DateTable
  where Date = cast(getdate() as date)
)
select Period,
       (select min(Date) from CStart) as StartDate,
       (select max(Date) from CEnd) as EndDate 
from CPeriod

SEデータのテスト

于 2013-01-04T14:42:33.850 に答える
1

このコードを試してみてください

DECLARE @TODAYSPERIOD AS VARCHAR(2)

SET @TODAYSPERIOD = (SELECT PERIOD FROM MYTABLE
                    WHERE DATE = (DATEADD(D, DATEDIFF(D, 0, GETDATE()), 0)))

SELECT MAX(DATE), MIN(DATE), @TODAYSPERIOD FROM MYTABLE
WHERE PERIOD = @TODAYSPERIOD AND DATE BETWEEN ((DATEADD(D, DATEDIFF(D, 0, GETDATE()), 0)) - 45) AND ((DATEADD(D, DATEDIFF(D, 0, GETDATE()), 0)) + 45)

基本的に、テーブル(上記のコードでは「MYTABLE」と呼ばれます)を使用して期間を検索し、半径45日以内(現在の日付の前後の両方)の日付のみを取得します。今日と同じ期間。

お役に立てれば!

于 2013-01-04T14:44:59.963 に答える
0

試すことができます(私のテストデータでは、56日が特定の期間で最大の日数でした)

SELECT A.period
     , MIN( B.date )
     , MAX( B.date )
  FROM dates A
 INNER JOIN dates B
    ON A.date >= DATEADD( dd, -56, B.date )
   AND A.date <= DATEADD( dd, 56, B.date )
   AND A.period = B.period 
 GROUP BY A.period
于 2013-01-04T14:50:33.777 に答える
0

テーブルに日付のギャップがなく、日付ごとに1行しかない場合は、次のように使用できます。

; WITH cte AS
  ( SELECT
        a.Date AS StartDate
      , b.Date AS EndDate
      , a.Period
      , ROW_NUMBER() OVER (ORDER BY a.Date) AS rn
    FROM tableX AS a
      LEFT JOIN tableX AS b
        ON  DATEADD(day, -1, a.Date) = b.Date
    WHERE a.Period <> b.Period 
       OR b.Date IS NULL 
  )
SELECT
    a.StartDate
  , COALESCE(b.EndDate, (SELECT MAX(Date) FROM tableX)) AS EndDate
  , a.Period
FROM
    cte AS a
  LEFT JOIN 
    cte AS b
      ON a.rn + 1 = b.rn ;

SQLでテスト済み-Fiddle

于 2013-01-04T15:37:01.780 に答える