-3
INSERT INTO @blah (ID, Date)
    VALUES (123, '11/12/2012')
    VALUES (124, '11/30/2012')
    VALUES (125, '11/28/2012')
    VALUES (126, '12/1/2012')
    VALUES (127, '12/30/2012')
    VALUES (128, '12/25/2012')
    VALUES (129, '12/26/2012')

日付がそれぞれの月の最後の週で、2か月前の行を取得したいと思います。今月は2013年1月なので、2012年12月と2012年11月の最終週が欲しいです。

最終的なオプションは、月の最後の丸1週間の例です。2012年12月= 12 / 23-12 / 29ですが、今のところ、月の最後の7日間はかかりません。

過去2か月の取得方法は知っていますが、それぞれの月の最終週の取得方法がわかりません。

select
    *
from
    @blah
where
    dateDiff(month,date,getdate()) < 2 ---only look at the last two months
4

4 に答える 4

5

これは、指定された要件(過去2か月の最後の丸1週間)を満たしています。

SET DATEFIRST 1;

DECLARE @s DATE = GETDATE(), @s1 DATE, @s2 DATE;
SET @s = GETDATE();

-- last day of last month:
SET @s1 = DATEADD(DAY, -DAY(@s), @s);

-- last day of previous month:
SET @s = DATEADD(MONTH, -1, @s);
SET @s2 = DATEADD(DAY, -DAY(@s), @s);

SELECT 
 @s1 = DATEADD(DAY, -7, DATEADD(DAY, -DATEPART(WEEKDAY, @s1) % 7, @s1)),
 @s2 = DATEADD(DAY, -7, DATEADD(DAY, -DATEPART(WEEKDAY, @s2) % 7, @s2));

SELECT col1, col2, etc. 
FROM dbo.table
  WHERE 
  (date_column >= @s1 AND date_column < DATEADD(DAY, 7, @s1)
  OR
  (date_column >= @s2 AND date_column < DATEADD(DAY, 7, @s2);

これをより動的にするために(人々がたくさんの仕事をした後ではなく、最初にこれらの要件を述べるために最善を尽くす必要があります)、あなたは言うことができます:

DECLARE @NumberOfMonthsIReallyWanted INT = 3;

DECLARE @i INT = 1, @d DATE = GETDATE();
DECLARE @t TABLE(d DATE);

WHILE @i <= @NumberOfMonthsIReallyWanted
BEGIN
  SET @d = DATEADD(MONTH, -@i, @d)

  INSERT @t(s) SELECT DATEADD(DAY, -7, DATEADD(DAY,  
   -DATEPART(WEEKDAY, DATEADD(DAY, -DAY(@d), @d)) % 7, 
   DATEADD(DAY, -DAY(@d), @d)));

  SET @i += 1;
END

SELECT src.col1, src.col2, etc. 
  FROM dbo.table AS src
  INNER JOIN @t AS t
  ON src.date_column >= t.d AND src.date_column < DATEADD(DAY, 7, t.d);

LIKE日付比較クエリに使用するようにだれにも説得させないでください。これはsargability(インデックスを使用できないことを意味します)を殺すだけでなく、このような問題の場合、どの文字列パターンに一致するかをどのように決定しますか?難しいのは、条項を作成することではなく、魔法のプレースホルダーWHEREに何を入力するかです。(Your Dates go here)そして、日付の範囲を見つけたとき、本当に14の個別のLIKE表現が必要ですか?私はしません。

于 2013-01-14T21:03:14.283 に答える
0

これはOracleで機能します-いくつかのアイデアを提供し、うまくいけば役立つかもしれません:

-- Last weeks of last two months -- 
SELECT mydate
  , TRUNC(mydate, 'iw') wk_starts
  , TRUNC(mydate, 'iw') + 7 - 1/86400 wk_ends
  , TO_NUMBER (TO_CHAR (mydate, 'IW')) ISO_wk#  
 FROM
  ( -- Last week = Last day of the year (hardcoded) - 1 week --
   SELECT(CASE WHEN start_date = To_Date('12/31/2012', 'mm/dd/yyyy') THEN start_date-7 ELSE start_date END) mydate 
     FROM
     ( -- Last 2 months --
      SELECT Add_Months(Last_Day(Trunc(SYSDATE)), - LEVEL) start_date
        FROM dual
     CONNECT BY LEVEL <= 2
    )
 )
/
于 2013-01-14T22:21:00.263 に答える
0
declare @blah table (ID int, [Date] datetime)
INSERT INTO @blah (ID, [Date])
select 123, '20121112'
union select 124, '20121130'
union select 125, '20121128'
union select 126, '20121201'
union select 127, '20121230'
union select 128, '20121225'
union select 129, '20121226'

select ID, [Date], datepart(week, [Date])
from @blah
where
    datediff(month, [Date], getdate()) in (1,2)
    and
    datepart(week, [Date]) = datepart(
                                week, 
                                dateadd(
                                    day, 
                                    -datepart(day,dateadd(month, 1, [Date])), 
                                    dateadd(month, 1, [Date])))
于 2013-01-14T21:06:41.700 に答える
-3

これは、SQLサーバーに多少依存します。この例はOracleに似ています。各サーバーには、SYSDATEやNOWなどの独自の機能があります。

例えば。

SELECT * from blah WHERE TO_CHAR(TRUNC(data), MM/DD/YYYY) < '01/14/2013'
于 2013-01-14T19:41:32.370 に答える