Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Добрый день!

Что-то у меня не получается сообразить, как сделать подобную выборку: нужно выбрать даты в промежутке (например, с 1.1.2012 по 1.6.2012), притом что это будут вторники и среды, (начиная с наименьшего) и далее с промежутком между датами 14 дней. Например:

3.1.2012 (вт), 4.1.2012 (ср)
17.1.2012 (вт), 18.1.2012 (ср)

Если у кого-то есть идеи КАК это сделать в t-sql, заранее спасибо!
25 авг 11, 13:20    [11177585]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Glory
Member

Откуда:
Сообщений: 104751
cavalero
нужно выбрать даты

Выбрать откуда ?
25 авг 11, 13:23    [11177604]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Glory
cavalero
нужно выбрать даты

Выбрать откуда ?



Вот из этой таблицы:

SET NOCOUNT ON;
IF OBJECT_ID('[master].[dbo].[Dates]','U') IS NULL
BEGIN
 CREATE TABLE [master].[dbo].[Dates]([Date] DATETIME NOT NULL, CONSTRAINT [pkDates] PRIMARY KEY CLUSTERED([Date]));
 WITH [T]([Date]) AS
 (
  SELECT CAST('2001' AS DATETIME)
  UNION ALL
  SELECT DATEADD(DAY,1,[Date]) FROM [T] WHERE [Date]<'2021'
 )
 INSERT [master].[dbo].[Dates]([Date])
 SELECT [Date]
 FROM [T]
 OPTION(MAXRECURSION 0);
END;

25 авг 11, 13:27    [11177653]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Glory
Member

Откуда:
Сообщений: 104751
И что мешает добавить в запрос фильтрацию "с 1.1.2012 по 1.6.2012" ?
25 авг 11, 13:29    [11177665]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Glory
И что мешает добавить в запрос фильтрацию "с 1.1.2012 по 1.6.2012" ?


То, что это должны быть вторники и среды и между ними должно быть 2 недели (в принципе количество дней может быть произвольное)

Это расчет туристических групп: например, с 1.1.2012 по 1.6.2012 каждые 2 недели во вторник и среду начинается тур или экскурсия и тд. Может каждый месяц начинаться или каждую неделю, по-разному.
25 авг 11, 13:35    [11177727]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Glory
Member

Откуда:
Сообщений: 104751
cavalero
То, что это должны быть вторники и среды

Для определения дня недели есть документированная функция

cavalero
и между ними должно быть 2 недели

Для сравнения значений одной записи с другой придется писать подзапрос
25 авг 11, 13:37    [11177767]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Glory
cavalero
То, что это должны быть вторники и среды

Для определения дня недели есть документированная функция

cavalero
и между ними должно быть 2 недели

Для сравнения значений одной записи с другой придется писать подзапрос


Хм? Какой подзапрос? Есть мнение, что тут без цикла или курсора не обойтись.
25 авг 11, 13:41    [11177810]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Glory
Member

Откуда:
Сообщений: 104751
cavalero
Хм? Какой подзапрос?

Обыкновенный, для сравнения двух записей
25 авг 11, 13:42    [11177822]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Glory
cavalero
Хм? Какой подзапрос?

Обыкновенный, для сравнения двух записей


А откуда 2 записи? У меня дальше такого запроса мысль не идет

SELECT D.date, D.num
FROM
(
	SELECT D.Date date,ROW_NUMBER() OVER (ORDER BY D.date) num
	FROM [master].[dbo].[Dates] D
	WHERE D.Date>='20120101' AND D.Date<='20120601' AND datepart(dw,D.Date) IN (3,4)
) D

25 авг 11, 13:56    [11177965]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Glory
Member

Откуда:
Сообщений: 104751
cavalero
А откуда 2 записи? У меня дальше такого запроса мысль не идет

Текущую и проверяемую потому что
25 авг 11, 13:57    [11177978]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
declare
  @startDate datetime = '20120101',
  @stopDate datetime = '20120601';

with Q(dt) as
(
  select dateadd(day, 1, dateadd(week, datediff(week, '', @startDate), ''))
  union all
  select dateadd(day, 2, dateadd(week, datediff(week, '', @startDate), ''))
  union all
  select dateadd(week, 2, dt)
    from Q
   where dt < dateadd(week, -2, @stopDate)
)
select *
  from Q
 order by 1
option (maxrecursion 0)
типа такого?
25 авг 11, 14:03    [11178057]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Glory
Member

Откуда:
Сообщений: 104751
SELECT D.date, D.num
FROM
(
	SELECT D.Date date,ROW_NUMBER() OVER (ORDER BY D.date) num
	FROM [master].[dbo].[Dates] D
	WHERE D.Date>='20120101' AND D.Date<='20120601' AND datepart(dw,D.Date) IN (3,4)
 AND ((DATEADD(dd, -14, d.date) between '20120101' AND '20120601') 
          OR (DATEADD(dd, 14, d.date) between '20120101' AND '20120601') )
) D
25 авг 11, 14:06    [11178090]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
Glory
SELECT D.date, D.num
FROM
(
	SELECT D.Date date,ROW_NUMBER() OVER (ORDER BY D.date) num
	FROM [master].[dbo].[Dates] D
	WHERE D.Date>='20120101' AND D.Date<='20120601' AND datepart(dw,D.Date) IN (3,4)
 AND ((DATEADD(dd, -14, d.date) between '20120101' AND '20120601') 
          OR (DATEADD(dd, 14, d.date) between '20120101' AND '20120601') )
) D

IN (3,4) - это какие дни недели?
25 авг 11, 14:12    [11178163]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Зайцев Фёдор
declare
  @startDate datetime = '20120101',
  @stopDate datetime = '20120601';

with Q(dt) as
(
  select dateadd(day, 1, dateadd(week, datediff(week, '', @startDate), ''))
  union all
  select dateadd(day, 2, dateadd(week, datediff(week, '', @startDate), ''))
  union all
  select dateadd(week, 2, dt)
    from Q
   where dt < dateadd(week, -2, @stopDate)
)
select *
  from Q
 order by 1
option (maxrecursion 0)
типа такого?


Да, вроде бы оно! Спасибо! А у рекурсии нет ограничений на количество циклов?
25 авг 11, 14:19    [11178230]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Glory
SELECT D.date, D.num
FROM
(
	SELECT D.Date date,ROW_NUMBER() OVER (ORDER BY D.date) num
	FROM [master].[dbo].[Dates] D
	WHERE D.Date>='20120101' AND D.Date<='20120601' AND datepart(dw,D.Date) IN (3,4)
 AND ((DATEADD(dd, -14, d.date) between '20120101' AND '20120601') 
          OR (DATEADD(dd, 14, d.date) between '20120101' AND '20120601') )
) D


Выдает даты: 3.1, 4.1, 10.1, 11.1 -- интервал 7 дней
25 авг 11, 14:21    [11178246]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
WITH [T]([Date]) AS
 (
  SELECT CAST('2001' AS DATETIME)
  UNION ALL
  SELECT DATEADD(DAY,1,[Date]) FROM [T] WHERE [Date]<'2021'
 )
,D([Date],N) AS
 (
  SELECT [Date], DENSE_RANK()OVER(ORDER BY DATEDIFF(DAY,0,[Date])/7)
  FROM [T]
  WHERE DATEDIFF(DAY,0,[Date])%7 IN(1,2) AND [Date]>='2012' AND [Date]<'20120602'
 )
INSERT [dbo].[Dates]([Date])
SELECT [Date]
FROM [D]
WHERE N%2=1
OPTION(MAXRECURSION 0);
25 авг 11, 14:28    [11178312]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
cavalero,

обратите внимание на зависимость предлагаемых Вам решений от параметров SET DATEFIRST и SET LANGUAGE
(мой ответ от них не зависит)
25 авг 11, 14:31    [11178327]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
iap
(мой ответ от них не зависит)

мой тоже, вообще-то )
25 авг 11, 14:33    [11178347]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Зайцев Фёдор
iap
(мой ответ от них не зависит)

мой тоже, вообще-то )
Я просто советовал обратить на это внимание.
Во всё не углублялся при этом.
DATEPART(dw,...), например, точно зависит.
25 авг 11, 14:42    [11178456]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
Спасибо всем большое! Проблема решена! Всё-таки рекурсия в sql не для моих мозгов :) А с днями недели ситуация такая: эти вторники и понедельники тоже в базе хранятся в виде smallint, при том, что первый день недели -- воскресенье, в соответстии с настройками сервера. Поэтому datepart(dw,xx) и данные в таблице дней недели говорят на одном языке :)
25 авг 11, 15:35    [11179036]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
cavalero
Спасибо всем большое! Проблема решена! Всё-таки рекурсия в sql не для моих мозгов :) А с днями недели ситуация такая: эти вторники и понедельники тоже в базе хранятся в виде smallint, при том, что первый день недели -- воскресенье, в соответстии с настройками сервера. Поэтому datepart(dw,xx) и данные в таблице дней недели говорят на одном языке :)
Говнокод детектед!

И странно: сначала Вы говорили про вторники и среды, а сейчас вдруг - про понедельники и вторники...
25 авг 11, 15:53    [11179252]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
iap
cavalero
Спасибо всем большое! Проблема решена! Всё-таки рекурсия в sql не для моих мозгов :) А с днями недели ситуация такая: эти вторники и понедельники тоже в базе хранятся в виде smallint, при том, что первый день недели -- воскресенье, в соответстии с настройками сервера. Поэтому datepart(dw,xx) и данные в таблице дней недели говорят на одном языке :)
Говнокод детектед!

И странно: сначала Вы говорили про вторники и среды, а сейчас вдруг - про понедельники и вторники...



Почему это говнокод? Про вторники - понедельники попутал. В примере вторник и среда. Жара-с.
25 авг 11, 19:06    [11180975]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
cavalero
iap
пропущено...
Говнокод детектед!

И странно: сначала Вы говорили про вторники и среды, а сейчас вдруг - про понедельники и вторники...



Почему это говнокод?
Потому что зависит от неявных внешних факторов.
25 авг 11, 20:18    [11181250]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
cavalero
Member

Откуда: Прага
Сообщений: 247
iap
cavalero
пропущено...



Почему это говнокод?
Потому что зависит от неявных внешних факторов.



Каких? Что на разных серверах первый день недели может быть произвольный? Для серверов, где это крутится всегда стоит установка, что перывый день недели -- воскресенье. В клиентской части это тоже учитывается. Так что зря вы так.
26 авг 11, 12:48    [11184281]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать нужные даты?  [new]
Зайцев Фёдор
Member

Откуда: Лужки
Сообщений: 5308
cavalero
Для серверов, где это крутится всегда стоит установка

Это обеспечивается автором кода с datepart(dw, ...) ? Если нет, автор не имеет права делать таких допущений.
26 авг 11, 12:52    [11184346]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить