2012-03-08 3 views
1

Я пытаюсь написать sql-запрос, чтобы получить счет на прошлой неделе в формате mm/count/yyyy. В моей ситуации среда начинает новую неделю. Итак, сегодня 8 марта 2012 года - вторая неделя марта, а последняя неделя - 03/01/2012. Обратите внимание, что 01 означает, что счет недели не указан. Если рассмотреть 1 марта 2012 года, последняя неделя должна быть последней недели февраля, которая составляет 02/05/2012Как получить счет на прошлой неделе с помощью SQL-запроса?

Обновление: Спасибо за комментарий Стива, напомнив мне, чтобы убрать мой вопрос здесь. Каждый месяц начинается с первой среды. Таким образом, 03/01/2012 начинается с 7 марта 2012 года по 13 марта 2012 года

Любое решение для запросов sql?

Я использую SQL-сервер

+1

Что СУРБД вы используете? У некоторых есть встроенные функции, чтобы получить номера недели ... –

+0

OP не хочет номер недели, он хочет подсчитать количество дней с начала месяца. –

+0

@GuillaumePoussel Номер недели может использоваться для определения предыдущей недели, а некоторые API-интерфейсы позволяют выбрать день, который начинается с недели - в среду. –

ответ

1

в оракула:

select to_char(sysdate, 'w') from dual 
+0

Забудьте упомянуть, что я использую SQL-сервер, спасибо чувак. –

0

В SQL Server эти запросы возвращают 1,1,2,5

select ((DATEPART(dd, 'March 01, 2012')-1)/7) + 1 
select ((DATEPART(dd, 'March 07, 2012')-1)/7) + 1 
select ((DATEPART(dd, 'March 08, 2012')-1)/7) + 1 
select ((DATEPART(dd, 'March 31, 2012')-1)/7) + 1 

Так что это может быть, что вам необходимо

declare @dt datetime = 'March 31, 2012' 
select 
    CONVERT(nvarchar(4), DATEPART(month,@dt)) + '/' + 
    CONVERT(nvarchar(4), ((DATEPART(dd, @dt)-1)/7) + 1) + '/' + 
    CONVERT(nvarchar(4), DATEPART(year,@dt)) 

который производит '3/5/2012 '

2

Для того, Я не могу понять ваше фанковое определение «на прошлой неделе» по двум примерам, поэтому я не могу его кодировать.

DECLARE 
    @Now datetime, 
    @Today datetime, 
    @MonthStart datetime, 
    @WeekCount int, 
    @Result varchar(10) 

SET @Now = GetDate() 
SET @Today = DateAdd(dd, DateDiff(dd, 0, @Now), 0) 
SET @MonthStart = DateAdd(mm, DateDiff(mm, 0, @Today), 0) 

    -- relative to the actual day the month started 
SET @WeekCount = ((DatePart(dd, @Today)-1)/7) + 1 

    -- relative to Sunday 
--SET @WeekCount = (DatePart(week, @Today) - (DatePart(week, @MonthStart) + 1 

SET @Result = convert(varchar(10), @Today, 101) 
SET @Result = 
    LEFT(@Result, 3) -- month/ 
    + RIGHT('z00' + convert(varchar(2), @WeekCount), 2) -- week with zero pad 
    + RIGHT(@Result, 5) -- /year 

SELECT 
    @Now as TheNow, 
    @Today as Today, 
    @MonthStart as MonthStart, 
    @WeekCount as WeekCount, 
    @Result as Result 

Смотрите также SET DATEFIRST

+0

Для любознательных, z в строковом литерале запрещает tsql преобразовывать его в int literal и затем использовать целочисленное добавление. –

+0

«z» не требуется. Это важные кавычки. SQL Server не будет преобразовывать ни один из операндов [цитируемый строковый литерал] + [типизированная строка] в целое число. В любом случае SQL Server, как сильно типизированный язык, будет принимать решения о приведении операндов в выражения смешанного типа на основе типов и операторов, а не фактических значений. В любой ситуации, когда '00' будет преобразован в целое число, вместо этого вместо 'z00' произойдет ошибка. (Другое решение правильно (100 + @ WeekCount, 2).) –

0
SELECT 
    RIGHT(100 + MONTH(D)  , 2) + '/' + 
    RIGHT(100 + (DAY(D) + 6)/7, 2) + '/' + 
    DATENAME(YEAR, D) 
FROM (
    SELECT DATEADD(WEEK, -1, GETDATE()) AS D 
) s 
1

@Steven,

К сожалению, это не укладывалось в качестве комментария.

Ваше описание «[nth] week in [month]» не ясен. Ваша неделя начинается в среду. Февраля первый был среда, поэтому недели в феврале 2012 года, если на самом деле есть 5 из них,

  1. 1-7 февраля
  2. февраля 8-14
  3. февраля 15-21
  4. 22-28 февраля и
  5. 29 февраля - 6 марта

Вы описываете 8 марта как в «вторую неделю марта,» поэтому первая неделя марта должна быть на прошлой неделе, что я s 29 февраля - 6 марта. Обратите внимание, что это тоже то, что вы называете «последней (пятой) неделей в феврале».

По вашему описанию, дни, которые вы пишете как '02/05/2012 'и '03/01/2012', равны той же неделе с разными названиями.

Что такое правило, которое позволяет узнать, что

  1. Вы хотите такой же «на прошлой неделе», когда вы запускаете программу 1 марта, как при запуске 8 марта
  2. Вы хотите на этой неделе (которая то же самое), описанное по-разному в этих двух случаях.

У вас возникли ошибки в этом вопросе.

Как только вы сможете описать, что вам нужно, это будет легко запрограммировать. Если вы не знаете, чего хотите, программировать будет невозможно.

+0

02/05/2012 и 03/01/2012 - это не та же неделя. 02/05/2012 означает дату с 29 февраля по 6 марта. 03/01/2012 означает дату с 7 марта по 13 марта. Каждый месяц начинается с первой среды. –

+0

@Steven: Не могли бы вы объяснить, почему вы написали в своем вопросе, что «8 марта 2012 года - вторая неделя марта»? Вы хотите получить результат, когда он будет запущен 8 марта, чтобы быть неделю 7 марта - 13 марта? Я бы не описал это как «счет на прошлой неделе», как вы это выразили. –

0

Я думаю, что это должно сделать это, я не получаю значение на прошлой неделе, потому что это путано, и ответ более чист, так что вы можете просто добавить DATEADD(day,-7,date).

SET DATEFORMAT YDM 
CREATE TABLE #Dates (Date DATETIME) 
INSERT INTO #Dates VALUES ('2012-31-03'); 
INSERT INTO #Dates VALUES ('2012-15-02'); 
INSERT INTO #Dates VALUES ('2012-02-04'); 
INSERT INTO #Dates VALUES ('2012-02-05'); 

WITH Mondays as (
SELECT DATEADD(week, DATEDIFF(week,0, DATEADD(day,6-DATEPART(day,d.Date),d.Date)), 0) FirstMonday, 
     DATEADD(week, DATEDIFF(week,0, DATEADD(day,6-DATEPART(day,DATEADD(month, -1, d.Date)),DATEADD(month, -1, d.Date))), 0) FirstMondayOfLastMonth, 
     d.Date 
FROM #Dates d), 
Wednesday as (
SELECT CASE WHEN DATEPART(day,m.FirstMonday) <= 5 
      THEN DATEADD(day,2,m.FirstMonday) 
      ELSE DATEADD(day,-5,m.FirstMonday) END FirstWednesday, 
     CASE WHEN DATEPART(day,m.FirstMondayOfLastMonth) <= 5 
      THEN DATEADD(day,2,m.FirstMondayOfLastMonth) 
      ELSE DATEADD(day,-5,m.FirstMondayOfLastMonth) END FirstWednesdayOfLastMonth, 
     m.Date 
FROM Mondays m) 
SELECT w.Date, 
     CASE WHEN w.Date >= w.FirstWednesday THEN 
      RIGHT('0' + CAST(DATEPART(month,w.Date) AS NVARCHAR(2)),2) 
      + '/0' + CAST(DATEDIFF(week,w.FirstWednesday, w.Date) + 1 AS NVARCHAR(2)) 
      + '/' + CAST(DATEPART(year,w.Date) AS NVARCHAR(4)) 
     ELSE 
      RIGHT('0' + CAST(DATEPART(month,w.FirstWednesdayOfLastMonth) AS NVARCHAR(2)),2) 
      + '/0' + CAST(DATEDIFF(week,w.FirstWednesdayOfLastMonth, w.Date) + 1 AS NVARCHAR(2)) 
      + '/' + CAST(DATEPART(year,w.FirstWednesdayOfLastMonth) AS NVARCHAR(4)) 
     END AS weekDate 
FROM Wednesday w 

DROP TABLE #Dates 

Результат: Дата weekDate

2012-03-31 00: 00: 00,000 03/04/2012

2012-02-15 00: 00: 00,000 02/03/2012

2012-04-02 00: 00: 00,000 03/05/2012

2012-05-02 00: 00: 00,000 05/01/2012