powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите понять CTE
38 сообщений из 38, показаны все 2 страниц
Помогите понять CTE
    #38325768
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не могу понять здесь рекурсия получается что ли?
Просто в моем понимании как происходит:
в первом селекте 1-й день месяца и название дня
объединяется со вторым днем и назанием дня. А вот дальше что происходит?
Зы: А где здесь форум по sql просто
WITH CTE AS
(
SELECT DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE())[FIRST SUNDAY DATE],DATENAME(DW,DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE()))[DAY NAME]
UNION ALL
SELECT DATEADD(D,1,[FIRST SUNDAY DATE]),DATENAME(DW,DATEADD(D,1,[FIRST SUNDAY DATE]))FROM CTE
)
SELECT [DAY NAME] FROM CTE
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325773
Фотография Сергей Викт.
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobonickЗы: А где здесь форум по sql просто

А простоSQL это СУБД новая?

CTE рекурсивный. Возвращает вам список дат с названиями дней недели, начиная с первого числа текущего месяца. Сваливается по max recursion)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325774
Фотография Shakill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325776
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
* А где здесь форум по sql просто есть?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325777
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНе могу понять здесь рекурсия получается что ли?

Да, ибо CTE использует само себя же.
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325780
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobonick* А где здесь форум по sql просто есть?

Это тот sql, который "просто СУБД" используют?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325826
Фотография StarikNavy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobonick* А где здесь форум по sql просто есть?

форума "просто sql" здесь нету
http://ru.wikipedia.org/wiki/SQL
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325856
Фотография StarikNavy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Отступления от стандартов
Несмотря на наличие международного стандарта ANSI SQL-92, многие компании, занимающиеся разработкой СУБД (например, Oracle, Sybase, Microsoft, MySQL AB), вносят изменения в язык SQL, применяемый в разрабатываемой СУБД, тем самым отступая от стандарта. Таким образом, появляются специфичные для каждой конкретной СУБД диалекты языка SQL.
(C)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325874
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
StarikNavyОтступления от стандартов
Несмотря на наличие международного стандарта ANSI SQL-92 , многие компании, занимающиеся разработкой СУБД (например, Oracle, Sybase, Microsoft, MySQL AB), вносят изменения в язык SQL, применяемый в разрабатываемой СУБД, тем самым отступая от стандарта. Таким образом, появляются специфичные для каждой конкретной СУБД диалекты языка SQL.
(C)CTE, однако, появился в ANSI SQL-99
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38325981
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ааааа, мой мозг разрывается просто=) Спасибо за ответы
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38326225
LexusR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
рекурсия в данном запросе бесконечная - надо как-нибудь ограничить
или так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SET ROWCOUNT 100
;WITH CTE AS
(
SELECT DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE())[FIRST SUNDAY DATE],DATENAME(DW,DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE()))[DAY NAME]
UNION ALL
SELECT DATEADD(D,1,[FIRST SUNDAY DATE]),DATENAME(DW,DATEADD(D,1,[FIRST SUNDAY DATE]))FROM CTE
)
SELECT [DAY NAME] FROM CTE 


или так
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
;WITH CTE AS
(
SELECT DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE())[FIRST SUNDAY DATE],DATENAME(DW,DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE()))[DAY NAME]
UNION ALL
SELECT DATEADD(D,1,[FIRST SUNDAY DATE]),DATENAME(DW,DATEADD(D,1,[FIRST SUNDAY DATE]))FROM CTE
WHERE [DAY NAME]<>'Sunday'
)
SELECT [DAY NAME] FROM CTE 


или еще как нибудь
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38326283
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LexusRили еще как нибудь

Угу. MAXRECURSION hint.
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38326284
Гость333
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pkarklinLexusRили еще как нибудь

Угу. MAXRECURSION hint.
Этот хинт не предназначен для ограничения бесконечной рекурсии.
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38326287
pkarklin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гость333Этот хинт не предназначен для ограничения бесконечной рекурсии.

Всмылсе?!

Код: sql
1.
2.
3.
4.
5.
6.
7.
WITH CTE AS
(
SELECT DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE())[FIRST SUNDAY DATE],DATENAME(DW,DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE()))[DAY NAME]
UNION ALL
SELECT DATEADD(D,1,[FIRST SUNDAY DATE]),DATENAME(DW,DATEADD(D,1,[FIRST SUNDAY DATE]))FROM CTE
)
SELECT [DAY NAME] FROM CTE OPTION (MAXRECURSION 5)



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
DAY NAME
------------------------------
понедельник
вторник
среда
четверг
пятница
суббота
Msg 530, Level 16, State 1, Line 1
Выполнение инструкции прервано. Максимальная рекурсия 5 была использована до завершения инструкции.
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38326290
Гость333
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гость333pkarklinпропущено...


Угу. MAXRECURSION hint.
Этот хинт не предназначен для ограничения бесконечной рекурсии.
То есть, конечно, сам по себе не предназначен. Без него не обойтись.
Способ ограничения рекурсии до заданного уровня видится таким:
Код: sql
1.
2.
3.
4.
5.
6.
7.
with cte as
(
  select ..., 1 as level from ...
  union all
  select ..., cte.level+1 as level from ... where cte.level < @MaxLevel
)
select * from cte option(maxrecursion 0)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38326293
Гость333
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pkarklinГость333Этот хинт не предназначен для ограничения бесконечной рекурсии.

Всмылсе?!

Код: sql
1.
... OPTION (MAXRECURSION 5)



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
DAY NAME
------------------------------
понедельник
вторник
среда
четверг
пятница
суббота
Msg 530, Level 16, State 1, Line 1
Выполнение инструкции прервано. Максимальная рекурсия 5 была использована до завершения инструкции.

Я имел в виду, что использование хинта самого по себе приводит к ошибке 530, а это плохо, если, скажем, код обёрнут в try-catch :-)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328011
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А не подскажете, возможно ли как-то cte применить, чтобы получить количество понедельников, вторников, сред... воскресений месяца при заданной дате.
Т.е.:
data mon tue .... sun
1.02.2012 4 5 3
6.07.2011 3 4 5

Вот в таком ключе
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328040
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно, нкжная вам ф-ция называеться
DATENAME
Код: sql
1.
select DATENAME ( dw , getdate() )
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328056
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxx,
а действительно... я было начал задумываться о мат.аппарате...
А все проще - развернуть месяц по дням, для каждого дня вычислить номер дня недели, свернуть в count по дням недели - и никакой математики... :)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328079
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДА, такие же мысли, только не номер дня недели, а сразу название, потом соответсвенно выборку по дню и подсчет. Но я не понимаю
вот есть столбец понедельник, вторник..воскресение - как его вывести?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328083
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pivot?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328088
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobonickdata mon tue .... sun
1.02.2012 4 5 3
6.07.2011 3 4 5
простите конечно,но как 1.02.2012 может содержать 4 понедельника,5 вторников и еще 3 воскресения ?
Развернуть просто PIVOT (гаратированные 7 колонок, если у вас не собственный календарь )
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328128
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maxx,
месяц, в котором есть дата 1.02.2012 - может :)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328135
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
XD
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328139
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007,

незнаю , может у них свой календарь
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328141
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007, Pivot, это классно. Но ведь я получу только за один месяц. Как мне применить это к остальным месяцам?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328142
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DATENAME - недетерминированная функция.
Поэтому иногда её применить не получится.

Лучше считать остаток от деления на 7 периода времени с 01.01.1900, выраженного в днях!
1 января 1900 был понедельником. Поэтому остаток, равный 0, означает "понедельник".
Число 0 без проблем конвертируется именно в '1900'.
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328167
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Во у меня какой календарь есть:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
DECLARE @FromMonth CHAR(6),@ToMonth CHAR(6);
SELECT @FromMonth='200101',@ToMonth='201401';
DECLARE @Language NVARCHAR(4000);
SET @Language=@@LANGUAGE;
IF @@LANGUAGE<>N'русский' SET LANGUAGE Russian;
WITH
 Dates(D)AS(SELECT CAST(@FromMonth+'01' AS DATETIME) UNION ALL SELECT DATEADD(DAY,1,D) FROM Dates WHERE D<DATEADD(DAY,-1,@ToMonth+'01'))
,WeekDays(Y,M,D,WD,N,WNo)AS(SELECT YEAR(D), MONTH(D), STR(DAY(D),2),(@@DATEFIRST+DATEPART(WEEKDAY,D))%7, DATENAME(MONTH,D),(DAY(D)-1+(@@DATEFIRST+DATEPART(WEEKDAY, CONVERT(CHAR(6),D,112)+'01')-2)%7)/7 FROM Dates)
,Calendar AS
(
 SELECT Y,M,WNo
, CASE WHEN WNo=0 AND M=1 THEN STR(Y,4) ELSE''END[Год]
, LEFT(CASE WNo WHEN 0 THEN CASE M WHEN 1 THEN REPLICATE('=',8)ELSE REPLICATE('-',8)END WHEN 2 THEN N ELSE''END,8)[Месяц]
, ISNULL([2],'')[Пн]
, ISNULL([3],'')[Вт]
, ISNULL([4],'')[Ср]
, ISNULL([5],'')[Чт]
, ISNULL([6],'')[Пт]
, ISNULL('['+[0]+']','')[Сб]
, ISNULL('['+[1]+']','')[Вс]
 FROM WeekDays PIVOT (MAX(D) FOR WD IN([0],[1],[2],[3],[4],[5],[6])) Pvt
)
SELECT [Год],[Месяц],[Пн],[Вт],[Ср],[Чт],[Пт],[Сб],[Вс] FROM Calendar ORDER BY Y,M,WNo OPTION(MAXRECURSION 0);
IF @@LANGUAGE<>@Language SET LANGUAGE @Language;

http://www.sql.ru/forum/519478/kalendar-nyneshnego-mesyaca

Сейчас бы по-другому сделал...
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328172
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobonick,
задачу-то сформулируйте хотя бы... полностью, а не с регулярными вводными :)
в старттопике была генерация дней от начала текущего месяца до конца света,
потом вопрос о количестве дней недели в текущем месяце,
теперь выясняется, что месяцев несколько...
что будет дальше?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328184
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ДЫ, просто задумка была как раз посчитать количество дней через CTE в месяце и сгруппировать их по дням недели, а потом pivot применить, но ведь у меня же еще месяц в зависимости от даты выбирается. А дат много. И нужно это все в таблицу вывести
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328191
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
boobonick,

Вам ещё не посоветовали сделать постоянную таблицу с датами лет на сто?
И таблицу с числами хотя бы от 0 до миллиона?

Сделайте. Не пожалеете. Все подобные задачи станут элементарными.
И сервер их обработает максимально эффективно.
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328259
Чтобы понять рекурсию,
нужно понять рекурсию :)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328291
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iap,
а разве это не одна и та же таблица??
с учетом dateadd(d,number,<базовая дата>) persisted ?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38328300
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Cygapb-007iap,
а разве это не одна и та же таблица??
с учетом dateadd(d,number,<базовая дата>) persisted ?Можно и одну.
У меня вот обе есть. Проиндексированные. Чего тут экономить-то?
К тому же в таблице с датами можно полезную информацию держать (праздник/не праздник, например)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38344200
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот, набросал,но теперь вопрос, как мне это все связать с несколькими месяцами? Т.е., я передаю,соединяю несколько месяцев, а мне в ответ месяц и сумму всех дней недели этих месяцев

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
WITH CTE AS
(
	SELECT DATEADD(D,-DATEPART(D,GETDATE())+1,GETDATE())[SUNDAY DATE]
	UNION ALL
	SELECT DATEADD(D,1,[SUNDAY DATE]) FROM CTE 
WHERE [SUNDAY DATE]<=DATEADD(D,-DATEPART(D,GETDATE()),DATEADD(M,1,GETDATE()))-1
)
SELECT Convert(varchar(7),[SUNDAY DATE],120)odate,
SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Monday' THEN 1 ELSE 0 END) Mon
, SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Tuesday' THEN 1 ELSE 0 END) Tue
, SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Wednesday' THEN 1 ELSE 0 END) Wed
, SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Thursday' THEN 1 ELSE 0 END) Thu
, SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Friday' THEN 1 ELSE 0 END) Fri
, SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Saturday' THEN 1 ELSE 0 END) Sat
, SUM(CASE datename(weekday,[SUNDAY DATE]) WHEN 'Sunday' THEN 1 ELSE 0 END) Sun

FROM CTE
group by Convert(varchar(7),[SUNDAY DATE],120)
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38344203
boobonick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е. примерно так должно быть:
Код: sql
1.
2.
3.
odate	Mon	Tue	Wed	Thu	Fri	Sat	Sun
2013-07	5	5	5	4	4	4	4
2013-05   4      5      4      5      4      4      4
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38344632
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в CTE генерируются все даты за один месяц - откуда второй строке взяться?
...
Рейтинг: 0 / 0
Помогите понять CTE
    #38344709
Cygapb-007
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
declare @date_from datetime='20130620', @date_to datetime='20130810'
set datefirst 1 -- неделя начинается с понедельника
select * 
from (
   select YM YEAR_MONTH, WD WEEKDAY, COUNT(*) qty
   from master..spt_values v 
   cross apply (select DAY=DATEADD(DAY, v.number, @date_from)) DAY
   cross apply (select 
      YM=LEFT(CONVERT(varchar,DAY,120),7),
      WD=DATEPART(WEEKDAY,DAY)
      ) YM
   where v.type='P' and v.number<=DATEDIFF(DAY, @date_from,@date_to)
   group by YM,WD
   )g
pivot(max(qty)for weekday in ([1],[2],[3],[4],[5],[6],[7]))p
order by YEAR_MONTH

YEAR_MONTH12345672013-0611122222013-0755544442013-081112221
...
Рейтинг: 0 / 0
38 сообщений из 38, показаны все 2 страниц
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Помогите понять CTE
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]