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

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

Не знаю как написать запрос, подскажите, пожалуйста.

Есть таблица со столбцами, OUID - идентификатор, A_CODE - строка, A_NAME - строка, A_DESIGN - идентификатор записи в таблице DESIGN.
Поле A_CODE представляет собой относительный адрес страницы сайта, например вида admin, admin/index, main/news/details и т.п, т.е. определенного формата - одно слово написанное латиницей или слова написанные латиницей разделенные слэшем /.
A_NAME имя страницы на русском языке, а A_DESIGN идентификатор записи о дизайне страницы.

Считается, что поле A_DESIGN обязательно заполнено у корневой страницы содержащей в A_CODE одно слово написанное латиницей, у других вложенных страниц, у которых A_CODE представляет собой слова через / поле A_DESIGN может быть заполнено а может и быть пустым. Таблица может содержать записи о нескольких корневых и вложенных в них страницах.

Пример таблицы:

OUID A_NAME A_CODE A_DESIGN
1 Главная1 main1 101
2 новости main1/news 101
3 подробно main1/news/detail NULL
4 Главная2 main2 102
5 товары main2/products NULL
6 подробно main2/products/detail NULL
7 комментарий main2/products/detail/com NULL


Необходимо из данной таблицы сделать select, в котором содержались бы все поля таблицы, но в поле A_DESIGN, которые в таблице равны NULL, были проставлены значения A_DESIGN корневых страниц. Корневая страница текущей записи определяется видимо по вхождению A_CODE корневой страницы в A_CODE текущей страницы.

Надо чтобы выбранная запросом таблица имела вид:

OUIDA_NAMEA_CODEA_DESIGN
1Главная1main1101
2новостиmain1/news101
3подробноmain1/news/detail101
4Главная2main2102
5товарыmain2/products102
6подробноmain2/products/detail102
7комментарийmain2/products/detail/comNULL


Вот вопрос как написать такой запрос, получающий такую таблицу из исходной?
Спасибо
29 окт 11, 21:58    [11521366]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
chugart
Member

Откуда:
Сообщений: 8
chugart,

Прошу прощение послеждняя строка в полученной таблице должна быть тоже такая

7 комментарий main2/products/detail/com 102
29 окт 11, 22:38    [11521431]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iljy
Member

Откуда:
Сообщений: 8711
chugart,

курите рекурсивные CTE.
29 окт 11, 23:07    [11521501]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
chugart
Member

Откуда:
Сообщений: 8
покурил, пришел к следующей конструкции:

with recursive PAG (OUID, A_NAME, A_CODE, A_DESIGN, A_PARENT)
as ( select OUID, A_NAME, A_CODE, A_DESIGN, A_PARENT 
          from CMS_SITEPAGE 
          where A_PARENT is null and A_DESIGN is not null
       union all
          select pg.OUID, pg.A_NAME,  pp.A_DESIGN, pg.A_PARENT
          from CMS_SITEPAGE pg
          inner join PAG pp
                    on pg.A_PARENT = pp.OUID
) 
select * from PAG

вроде верно, но не работает..:(
30 окт 11, 02:24    [11521867]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
qwerty112
Guest
chugart
...
вроде верно, но не работает..:(

"не работают" - негры в Африке (у них всё время отпуск и бананы с неба падают)
запрос выполняется и возвращает ошибку или не то что желал создатель ейный ... у вас какой случай ?

зы
рекурсивный запрсос - это когда во второй части юниона wnt, в with, используется первая ...
30 окт 11, 02:57    [11521876]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
chugart
Member

Откуда:
Сообщений: 8
В моем случае в запросе

WITH RECURSIVE pag 
as ( select OUID, A_NAME, A_CODE, A_DESIGN, A_PARENT 
          from CMS_SITEPAGE 
          where A_PARENT is null
    union all
          select pg.OUID, pg.A_NAME,  pp.A_DESIGN, pg.A_PARENT
          from CMS_SITEPAGE pg
          inner join pag pp on pg.A_PARENT = pp.OUID
          )
select * from pag

Выдается ошибка
Сообщение 102, уровень 15, состояние 1, строка 1
Неправильный синтаксис около конструкции "RECURSIVE".
30 окт 11, 03:00    [11521877]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
chugart
Member

Откуда:
Сообщений: 8
qwerty112,

автор
зы
рекурсивный запрсос - это когда во второй части юниона wnt, в with, используется первая ...


Прошу прощения, но не понял о чем вы говорите )
30 окт 11, 03:07    [11521878]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
qwerty112
Guest
chugart
qwerty112,

автор
зы
рекурсивный запрсос - это когда во второй части юниона wnt, в with, используется первая ...


Прошу прощения, но не понял о чем вы говорите )

"wnt" === "cte"

;with cte as 
(select 1 as xz union all select xz+1 from cte where xz <100)

select * from cte
30 окт 11, 03:14    [11521879]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
chugart
Member

Откуда:
Сообщений: 8
qwerty112, спасибо!

Ошибку нашел. Следующий код рабочий.

with pag 
as ( select OUID, A_NAME, A_CODE, A_DESIGN, A_PARENT 
          from CMS_SITEPAGE 
          where A_PARENT is null
    union all
          select pg.OUID, pg.A_NAME, pp.A_CODE, pp.A_DESIGN, pg.A_PARENT
          from CMS_SITEPAGE pg
          inner join pag pp on pg.A_PARENT = pp.OUID
    )
select * from pag

Почему только не прошла конструкция не понимаю.
with recurseive pag ....
30 окт 11, 03:28    [11521883]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iljy
Member

Откуда:
Сообщений: 8711
chugart,

потому что синтаксис надо использовать, а не придумывать.
30 окт 11, 11:03    [11522061]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
aleks2
Guest
Охренеть. Опять компом гвозди заколачивают, вместо того, чтоб взять молоток

select T.OUID, T.A_NAME, T.A_CODE, TT.A_DESIGN
FROM [Таблица] T
inner join [Таблица] TT
ON LEFT(T.A_CODE,CHARINDEX('/', T.A_CODE+'/')-1)=TT.A_CODE

и никакой рекурсии.

ЗЫ. Рекурсия - признак слабого программиста.
30 окт 11, 11:35    [11522097]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
iljy
chugart,

потому что синтаксис надо использовать, а не придумывать.
Справедливости ради надо сказать, что RECURSIVE описывается в ANSI SQL 1999.
Microsoft почему-то выкинул это ключевое слово. И, по-моему, совершенно напрасно.
Более читаемо было бы, согласитесь.
30 окт 11, 12:21    [11522181]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iljy
Member

Откуда:
Сообщений: 8711
iap
iljy
chugart,

потому что синтаксис надо использовать, а не придумывать.
Справедливости ради надо сказать, что RECURSIVE описывается в ANSI SQL 1999.
Microsoft почему-то выкинул это ключевое слово. И, по-моему, совершенно напрасно.
Более читаемо было бы, согласитесь.

В принципе да, но, поскольку слово нагрузки смысловой не несет, его скорее всего все равно бы пропускали, так же, как AS.
30 окт 11, 21:41    [11523289]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iljy
Member

Откуда:
Сообщений: 8711
aleks2
Охренеть. Опять компом гвозди заколачивают, вместо того, чтоб взять молоток

select T.OUID, T.A_NAME, T.A_CODE, TT.A_DESIGN
FROM [Таблица] T
inner join [Таблица] TT
ON LEFT(T.A_CODE,CHARINDEX('/', T.A_CODE+'/')-1)=TT.A_CODE

и никакой рекурсии.

ЗЫ. Рекурсия - признак слабого программиста.

Сильный ты наш программист, светоч форума, хоть где-нибудь в задаче сказано, что у всех вложенных таблиц A_DESIGN такое же, как у корневой? Я изменю вторую строку так
(2, 'новости', 'main1/news', 103),
и что твой чудо-запрос выдаст? Тролль-недоумник блин..


ТС, уточните постановку задачи чтоли.
30 окт 11, 21:44    [11523302]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
aleks2
Guest
iljy
Сильный ты наш программист, светоч форума, хоть где-нибудь в задаче сказано, что у всех вложенных таблиц A_DESIGN такое же, как у корневой? Я изменю вторую строку так
(2, 'новости', 'main1/news', 103),
и что твой чудо-запрос выдаст? Тролль-недоумник блин..


Слепой "сильный программист"? Да ишо и нервный.

chugart
Считается, что поле A_DESIGN обязательно заполнено у корневой страницы содержащей в A_CODE одно слово написанное латиницей, у других вложенных страниц, у которых A_CODE представляет собой слова через / поле A_DESIGN может быть заполнено а может и быть пустым. Таблица может содержать записи о нескольких корневых и вложенных в них страницах.



ЗЫ. Предлагаю отправить "нервного" программиста подлечиться в баню.
31 окт 11, 05:32    [11523903]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iap
Member

Откуда: Москва
Сообщений: 47144
iljy
iap
пропущено...
Справедливости ради надо сказать, что RECURSIVE описывается в ANSI SQL 1999.
Microsoft почему-то выкинул это ключевое слово. И, по-моему, совершенно напрасно.
Более читаемо было бы, согласитесь.

В принципе да, но, поскольку слово нагрузки смысловой не несет, его скорее всего все равно бы пропускали, так же, как AS.
Есть нагрузка.
Сейчас различить рекурсивное и нерекурсивное CTE можно только тщательно просматривая глазами текст
в попытке обнаружения какой-то там ссылки на имя CTE после какого-тот там UNION ALL.
Можно представить себе огромное CTE - это может быть непросто.

Но если человек написал RECURSIVE, то серверу ясно,
что текст CTE должен отвечать всем требованиям именно рекурсивного CTE.
Значит, если этот текст не содержит рекурсивной ссылки, он может выдать
сообщение об ошибке. То же самое в обратной ситуации (RECURSIVE нет, а ссылка на CTE есть)
Следовательно, речь идёт об обнаружении логических ошибок в запросе.
31 окт 11, 09:36    [11524178]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iljy
Member

Откуда:
Сообщений: 8711
aleks2
chugart
у других вложенных страниц, у которых A_CODE представляет собой слова через / поле A_DESIGN может быть заполнено а может и быть пустым.


Нигде не сказано, что заполнено обязательно тем же значением, что и поле у корневой страницы.
31 окт 11, 09:38    [11524186]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
iljy
Member

Откуда:
Сообщений: 8711
iap
iljy
пропущено...

В принципе да, но, поскольку слово нагрузки смысловой не несет, его скорее всего все равно бы пропускали, так же, как AS.
Есть нагрузка.
Сейчас различить рекурсивное и нерекурсивное CTE можно только тщательно просматривая глазами текст
в попытке обнаружения какой-то там ссылки на имя CTE после какого-тот там UNION ALL.
Можно представить себе огромное CTE - это может быть непросто.

Но если человек написал RECURSIVE, то серверу ясно,
что текст CTE должен отвечать всем требованиям именно рекурсивного CTE.
Значит, если этот текст не содержит рекурсивной ссылки, он может выдать
сообщение об ошибке. То же самое в обратной ситуации (RECURSIVE нет, а ссылка на CTE есть)
Следовательно, речь идёт об обнаружении логических ошибок в запросе.

Возможно. В принципе можно провести аналогию с введением в С++ ключевого слова override. Его тоже можно пропустить, но при указании оно здорово помогает ловить ошибки объявления. Другое дело, что случайно сделать рекурсивное CTE все-таки сложнее, чем случайно перепутать тип параметра у функции
31 окт 11, 09:42    [11524208]     Ответить | Цитировать Сообщить модератору
 Re: Задать значение ячейке в запросе на основе вхождения строк  [new]
aleks2
Guest
iljy
aleks2
пропущено...


Нигде не сказано, что заполнено обязательно тем же значением, что и поле у корневой страницы.


Точно зрение не в порядке

chugart
Необходимо из данной таблицы сделать select, в котором содержались бы все поля таблицы, но в поле A_DESIGN, которые в таблице равны NULL, были проставлены значения A_DESIGN корневых страниц.

Единственное, в чем я грешен - нет проверки на null. Исправляюсь

select T.OUID, T.A_NAME, T.A_CODE, ISNULL(T.A_DESIGN, TT.A_DESIGN) A_DESIGN
FROM [Таблица] T
inner join [Таблица] TT
ON LEFT(T.A_CODE,CHARINDEX('/', T.A_CODE+'/')-1)=TT.A_CODE
31 окт 11, 10:13    [11524406]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить