Формулы даты SQL - PullRequest
       8

Формулы даты SQL

3 голосов
/ 27 октября 2008

Мне нужна формула даты в Oracle SQL или T-SQL, которая будет возвращать дату предыдущей недели (например, дату последнего понедельника).

У меня есть отчеты с параметрами, которые запускаются каждую неделю, обычно с датами параметров понедельник-пятница или воскресенье-суббота предыдущей недели. Мне бы не хотелось вводить даты, когда я запускаю отчеты каждую неделю.

Данные находятся в Oracle, и я использую службы отчетов SQL Server 2005 (SSRS) для отчетов.

Ответы [ 7 ]

2 голосов
/ 27 октября 2008

Вот решение Oracle на понедельник.

select sysdate - 5 - to_number(to_char(sysdate,'D')) from dual

Вот примеры, которые извлекают любой конкретный день предыдущей недели.

SELECT sysdate - 6 - to_number(to_char(sysdate,'D')) LastSunday FROM dual;
SELECT sysdate - 5 - to_number(to_char(sysdate,'D')) LastMonday FROM dual;
SELECT sysdate - 4 - to_number(to_char(sysdate,'D')) LastTuesday FROM dual;
SELECT sysdate - 3 - to_number(to_char(sysdate,'D')) LastWednesday FROM dual;
SELECT sysdate - 2 - to_number(to_char(sysdate,'D')) LastThursday FROM dual;
SELECT sysdate - 1 - to_number(to_char(sysdate,'D')) LastFriday FROM dual;
SELECT sysdate - 0 - to_number(to_char(sysdate,'D')) LastSaturday FROM dual;

Если вам нужно, чтобы часть времени была 00:00:00, оберните стат в TRUNC (...).

2 голосов
/ 27 октября 2008

T-SQL:

SELECT 
  DateColumn,
  DateColumn - CASE DATEPART(dw, DateColumn) 
                WHEN 1 THEN 6
                ELSE DATEPART(dw, DateColumn) - 2
              END MondayOfDateColumn
FROM 
  TheTable

Вам также нужно, чтобы часть времени была "00:00:00"?

Если это так, добавьте это выражение в расчет:

DATEADD(dd, 0, DATEDIFF(dd, 0, DateColumn)) - CASE DATEPART(dw, /* etc. etc. */
1 голос
/ 27 октября 2008

(Oracle)

trunc (sysdate, 'IW') - дает понедельник этой недели

trunc (sysdate, 'IW') - 7 - дает понедельник прошлой недели

Это предполагает, что вы считаете понедельник первым днем ​​недели, что означает «IW» (неделя ISO). Если вы считаете воскресенье первым днем ​​недели ...

trunc (sysdate, 'W') + 1 - дает понедельник этой недели, в воскресенье это будет в будущем

trunc (sysdate, 'W') + 1-7 - дает понедельник прошлой недели

1 голос
/ 27 октября 2008

Вот мое решение, проверено на 8 дней.

SET DateFirst 7

DECLARE @Today datetime

SET @Today = '2008-10-22'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today
SET @Today = '2008-10-23'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today
SET @Today = '2008-10-24'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today
SET @Today = '2008-10-25'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today

SET @Today = '2008-10-26'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today
SET @Today = '2008-10-27'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today
SET @Today = '2008-10-28'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today
SET @Today = '2008-10-29'
SELECT DateAdd(wk, DateDiff(wk, 0, DateAdd(dd, -1, @Today)) - 1, 0) as PreviousMonday, @Today as Today

Вот проблема с воскресеньем:

SELECT
  DateDiff(wk, 0, '2008-10-25') as SatWeek, --5677
  DateDiff(wk, 0, '2008-10-26') as SunWeek, --5688
  DateDiff(wk, 0, '2008-10-27') as MonWeek  --5688

SELECT
  DatePart(dw, '2008-10-25') as SatPart,  --7
  DatePart(dw, '2008-10-26') as SunPart,  --1
  DatePart(dw, '2008-10-27') as MonPart,  --2
  convert(datetime,'2008-10-25') - (DatePart(dw, '2008-10-25') - 2)  as SatMonday,
  --'2008-10-20'
  convert(datetime,'2008-10-26') - (-1)  as SunMonday,
  --'2008-10-27'
  convert(datetime,'2008-10-27') - (DatePart(dw, '2008-10-27') - 2)  as MonMonday
  --'2008-10-27'

Многие из этих решений предоставляют одинаковый ответ для воскресенья и понедельника на одной и той же неделе. Старый понедельник не следует подавать в отставку, пока не наступит еще один понедельник.

1 голос
/ 27 октября 2008

Ознакомьтесь со списком функций даты в этом сообщении . Вы хотите это.

SELECT (DATEADD(wk,DATEDIFF(wk,0,GETDATE()) -1 ,0))

Они почти всегда математичны и не ориентированы на строки, поэтому они будут работать быстрее, чем операции с регистром или приведением.

0 голосов
/ 27 октября 2008

В Oracle:

Редактировать: Сделано более кратким

Редактировать: Ли Риффель опубликовал гораздо лучшее решение, чем мое.

select
  case when 2 = to_char(sysdate-1,'D') then sysdate - 1
       when 2 = to_char(sysdate-2,'D') then sysdate - 2
       when 2 = to_char(sysdate-3,'D') then sysdate - 3
       when 2 = to_char(sysdate-4,'D') then sysdate - 4
       when 2 = to_char(sysdate-5,'D') then sysdate - 5
       when 2 = to_char(sysdate-6,'D') then sysdate - 6
       when 2 = to_char(sysdate-7,'D') then sysdate - 7
  end as last_monday
from dual
0 голосов
/ 27 октября 2008

Решение T-SQL:

При условии, что для параметра SET DATEFIRST установлено значение по умолчанию (воскресенье = 7), дата последнего понедельника:

SELECT
DATEADD(dy, DATEPART(dw, GETDATE()) - 9, GETDATE())

«-9» означает возврат на одну неделю назад (-7), а затем с понедельника на 2 мы вычитаем еще 2 и добавляем день недели для текущего дня.

...