Создание номера week_ref для передачи в хранимую процедуру - PullRequest
2 голосов
/ 19 марта 2012

В настоящее время один из отчетов читает month_ref, который создается следующим образом:

((DATEPART(yy, month_date) - 1200) * 100) + DATEPART(mm, month_date) AS month_ref,
month_date, DATENAME(MONTH, month_date) + ' ' + DATENAME(YEAR, month_date) AS month_name

Я хотел бы создать что-то вроде week_ref?

Ссылка на месяц однозначно определяет месяц для года. Когда он передается в конкретную хранимую процедуру, sp отфильтрует результаты по месяцу ref.

Теперь я хочу создать еженедельный отчет - (понедельник - вс) и мне нужно однозначно определить week_ref, чтобы я мог отфильтровать результаты, используя sp.

Как я могу это сделать?

Ответы [ 4 ]

3 голосов
/ 19 марта 2012

Это даст вам уникальный номер для каждой недели с понедельника по воскресенье, и это не зависит от даты.

SELECT datediff(day, 0, month_date) / 7 week_ref FROM <table>

Это будет всегда возвращать целое число, как проверено здесь:

SELECT SQL_VARIANT_PROPERTY(datediff(day, 0, getdate()) / 7, 'BaseType')

Возвращает:

int
1 голос
/ 19 марта 2012

Хотя я считаю эту технику очень грязной, месяцами она работает.Это потому, что в году всегда 12 месяцев.

В течение нескольких недель это и грязно, и порочно.Некоторые годы имеют больше недель, чем другие, потому что некоторые недели охватывают более одного года.

Я бы рекомендовал вместо этого просто использовать DATEDIFF().

В зависимости от желаемого дня неделичтобы начать свои недели, нужно немного подсчитать ...

  - Sun as start of week = DATEDIFF(WEEK, -1, yourDate  )  
  - Mon as start of week = DATEDIFF(WEEK, -1, yourDate-1)  
  - Tue as start of week = DATEDIFF(WEEK, -1, yourDate-2)  
  - Wed as start of week = DATEDIFF(WEEK, -1, yourDate-3)  
  - Thu as start of week = DATEDIFF(WEEK, -1, yourDate-4)  
  - Fri as start of week = DATEDIFF(WEEK, -1, yourDate-5)  
  - Sat as start of week = DATEDIFF(WEEK, -1, yourDate-6)  

Я также рекомендую использовать это для расчетов за месяц.DATEDIFF(MONTH, <a base date>, <your date>), текущий действительно неуклюжий.

РЕДАКТИРОВАТЬ Примеры преобразования указанных значений обратно в DATETIME

  - Sun as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate  ), -1  )
  - Mon as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate-1), -1+1)
  - Tue as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate-2), -1+2)
  - Wed as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate-3), -1+3)
  - Thu as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate-4), -1+4)
  - Fri as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate-5), -1+5)
  - Sat as start of week = DATEADD(WEEK, DATEDIFF(WEEK, -1, yourDate-6), -1+6)
0 голосов
/ 19 марта 2012

Используйте календарную таблицу с (как минимум) 3 столбцами: base_date, month_ref и week_ref. Затем, чтобы получить ссылки на месяц и неделю (какими бы они ни были) на определенную дату, вы можете запросить их непосредственно из таблицы календаря, не используя трудно читаемые вложенные функции или другой «неочевидный» код:

select week_ref, month_ref
from dbo.calendar
where base_date = @my_date

Вы не объяснили, что на самом деле означают week_ref и month_ref, но если они являются просто числами, то у календарной таблицы есть существенное преимущество: она может поддерживать несколько разных определений. Например, вы можете захотеть поддерживать как номер недели ISO, так и свою собственную схему номеров внутренних недель. Вы также можете легко изменять значения в таблице, если ваша логика меняется, без изменения какого-либо кода.

Как общее замечание, календарная таблица обычно является лучшим решением, чем встроенные функции, особенно если ваши требования связаны с отчетностью.

0 голосов
/ 19 марта 2012

Использование

Select DATEPART(wk, GetDate())   --In your case month_date and not GetDate()

, чтобы получить неделю года назад, и затем вы можете использовать любую формулу, какую захотите, чтобы создать week_ref, но, как я вижу из ваших правок, это единственное, что вам нужно. Однако вы бы изменили свой month_ref на что-то вроде этого.

((DATEPART(yy, month_date) - 1200) * 10000) + (DATEPART(mm, month_date) * 100) + DATEPART(wk, month_date) AS month_ref

Тогда вам не нужно добавлять дополнительный столбец

...