Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Помогите составить рекурсивный запрос

Коллеги, помогите составить рекурсивный запрос.
Про рекурсивные CTE, конечно, читал, но составить запрос не могу. Просто не умею мыслить такими категориями.
Нужен пример и всё такое.

Есть таблица:
CREATE TABLE parent_child (
	[N] [int] IDENTITY(1,1) NOT NULL,
	[parent_id] [varchar](10) NOT NULL,
	[parent_rng] [int] NOT NULL,
	[child_id] [varchar](10) NOT NULL,
	[child_rng] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
	[parent_id] ASC,
	[child_id] ASC,
	[N] ASC
))

INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('_1Z00JIJI2',0,'_1Z00JIJI2',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('_1Z00JIJI2',0,'_1Z00JIJI2',1)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('_1Z00JIJI2',1,'B1YD13B28O',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('B1YD13B28O',0,'B1YD13BVHE',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('C2780K704W',0,'C1YD128OPG',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('C2780K704W',0,'C1YD12IK1E',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('C2780K704W',0,'C2780K704W',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('E33W0L3XYY',0,'E1YD12P8FU',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('E33W0L3XYY',0,'E1YD12WA3I',0)
INSERT INTO [parent_child]([parent_id],[parent_rng],[child_id],[child_rng]) VALUES('E33W0L3XYY',0,'E1YD1312WY',0)


Пара [parent_id],[parent_rng] и [child_id],[child_rng] - это идентификаторы узлов дерева.

Корни деревьев (их множество) это узлы, в которых [parent_id]=[child_id] and [parent_rng]=[child_rng], т.е. одинаковые значения в parent и child половинках.
Дочерние узлы содержат значения [parent_id],[parent_rng] родительского узла, и [child_id],[child_rng] - своего.
Например:
('_1Z00JIJI2',0,'_1Z00JIJI2',0) - корневой узел
('_1Z00JIJI2',0,'_1Z00JIJI2',1) - дочерний
('_1Z00JIJI2',1,'B1YD13B28O',0) - "внучатый"
И т.д., вложенность около 1000

Задача:
Раскрыть дерево в таблицу "общий предок" - "текущий узел".
Т.е. должно быть:

('_1Z00JIJI2',0,'_1Z00JIJI2',0)
('_1Z00JIJI2',0,'_1Z00JIJI2',1)
('_1Z00JIJI2',0,'B1YD13B28O',0)

Я знаю, что это просто. Но не могу уложить это в голове.
Помогите!
Ответ:
uaggster
Только я всё равно не могу понять, как оно работает!
Вопрос: Помогите составить MySQL запрос на выборку из дерева по трём таблицам.

Здравствуйте! Помогите, пожалуйста, правильно составить MySQL запрос на выборку со следующим условием:

Есть три таблицы:
1. TStructure (FID:INT(11), FIDparent:INT(11), FOtdelName:VARCHAR(32)) – хранит дерево структуры предприятия (FID-FIDparent),

2. TUsers (FID:INT(11), FIDstructure:INT(11), FUserName:VARCHAR(64)) – хранит пользователей, принадлежащих какому либо отделу предприятия методом TUsers.FIDstructure=TStructure.FID,

3. TReports (FID:INT(11), FIDStructrueOtdel:INT(11), FReport:VARCHAR(255)) – таблица с отчётами, принадлежащими какому либо отделу предприятия методом TReports.FIDStructrueOtdel=TStructure.FID.

TUsers.FIDstructure заранее известен. TReports.FIDStructrueOtdel может совпадать, а может и не совпадать с TUsers.FIDstructure, т.к. первый может указывать, в том числе, и на дочерние отделы, к которым пользователь не принадлежит на прямую, а только через родительское отношение в дереве TStructure. Составьте или помогите составить SELECT запрос так, чтобы получить все записи из таблицы TReports, принадлежащие и дочерние отделу, к которому относится пользователь (TUsers.FIDstructure).

P.S.: Не судите строго, первый раз прошу так в наглую, но заработался до того, что совсем отупел, думать больше не могу, еле пост написал, не спал 35 часов и времени отоспаться не дают. Помогите, пожалуйста, составьте для меня этот запрос.
Ответ: как то так
SELECT * FROM TReports r
JOIN (SELECT @index:=INSTR(@a,',') as coma_index,
@id:=SUBSTRING_INDEX(@a, ',', 1)  as id,
@a:=SUBSTRING(@a,IF(@index,@index+1,0)),
@a:=CONCAT_WS(IF(LENGTH(@a)>0,',',''),@a,(SELECT group_concat(FID) FROM TStructure WHERE FIDparent=@id)) as array
FROM TStructure,(SELECT @a:=${FIDstructure_Param}) as init
WHERE LENGTH(@a)>0) as m ON r.FIDStructrueOtdel=m.id
Вопрос: Не могу составить два запроса.

Здравствуйте, можете мне помочь составить два запроса?
1. как мне взять значение из таблицы user_personal в колонке name по айдишнику и вставить а другую таблицу?
2. Как мне проверить два колонки (id и user_id) есть ли значения этих ячеек в одной строке или нет?
Ответ:
artik12321
Здравствуйте, можете мне помочь составить два запроса?
1. как мне взять значение из таблицы user_personal в колонке name по айдишнику и вставить а другую таблицу?
2. Как мне проверить два колонки (id и user_id) есть ли значения этих ячеек в одной строке или нет?


update XXXX x
set yyy = ( select name from user_personal where user_id = x.user_id )
where xxx.pk = 42


select * from YYYY
where id is null and user_id is null




УЧИ SQL , или увольняйся!
Вопрос: Помогите составить MYSQL запрос из 2 таблиц

Помогите составить MYSQL запрос из 2 таблиц
Есть 2 таблицы:

Товары
----------------
id    | название
----------------
1     | огурцы
2     | помидоры
3     | морковка
4     | капуста

Свойства
------------------------
id товара | тип   | значение
------------------------
2         | вес   | 1200
2         | цвет  | красный
3         | вес   | 500
4         | вес   | 1200

Необходимо, например: получить список тораров, у которых "вес = 1200" и "цвет = красный".
Т.е. результатом должно быть:

----------------
id    | название
----------------
2     | помидоры
Ответ:
Код

SELECT t1.id, t1.name
FROM Goods t1, Properties t2
WHERE t1.id = t2.id
AND (t2.type, t2.value) IN (('вес','1200'),('цвет','красный'))
GROUP BY t1.id /* , t1.name */
HAVING COUNT(/* DISTINCT t2.type, t2.value */ *) = 2

Вопрос: Помогите составить сложный запрос

table
-----------
id
status
action
case_number
readiness_date

table1
-----------
id
mid // id- table
executor //INT
kilometrage
departure_date
survey_date

table2
-----------
id
mid // id- table
executor //INT
kilometrage
departure_date
survey_date

accounts
-----------
id
mid // id- table
account_num
account_sum

paid
-----------
id
mid // id- table
aid // id- accounts
executor //INT
exec_sum
exec_date

Нужно выбрать данные из:
table.status, table.action, table.case_number, table.readiness_date, table1.kilometrage, table2.kilometrage, accounts.account_num, accounts.account_sum, paid.exec_sum, paid.exec_date

где 
accounts.mid = table.id, 
table1.mid = table.id, table1.executor = $_POST[idexecutor] AND (table1.departure_date >= $_POST[range_date1] AND table1.departure_date <= $_POST[range_date2]) OR (table1.survey_date >= $_POST[range_date1] AND table1.survey_date <= $_POST[range_date2])
table2.mid = table.id, table2.executor = $_POST[idexecutor] AND (table2.departure_date >= $_POST[range_date1] AND table2.departure_date <= $_POST[range_date2]) OR (table2.survey_date >= $_POST[range_date1] AND table2.survey_date <= $_POST[range_date2])
paid.mid = table.id, paid.aid = accounts.id

Еще и сумму подбить по paid.exec_sum и accounts.account_sum

т.е. нужно выбрать данные где встречается определенный исполнитель (idexecutor) и события (departure_date,survey_date) попадают в в период между датами (range_date1,range_date2)
Несколько дней бьюсь ничего не получается. 
Помогите пожалуйста составить правильно запрос
Ответ:
Я здесь описал их кратко (table1 и table2), в реале они действительно почти индентичны, в них записываются данные людей двух категорий и часть полей отличается или отсутствует.

Есть главная таблица (условно) table, с ней связаны таблицы table1 и table2, а также accounts с связанная с ней paid (aid), в paid  присутствует mid (id главной) т.к. иногда нужно выводить данные в связке (table-paid).
Согласен что напахано, сильно не пинайте, опыта проектирования большой базы и сложных запросов нет.
Вопрос: Помогите с SQL-запросом. Буду Очень Признателен.

Всем доброе время суток.
Помогите составить SQL-запрос начинающему, не могу сообразить...
Буду очень и очень признателен.
Необходимо сделать выборку из таблицы `modx_site_content` присоединив к ней значение доп.полей, код из таблицы `modx_site_tmplvar_contentvalues` с именем name = "code" в таблице `modx_site_tmplvars` не могу сообразить как это сделать..
Наведите меня на мысль, как это сделать.
Ответ: SELECT * FROM `modx_site_content`
JOIN `modx_site_tmplvar_contentvalues` ON `modx_site_content`.`id`=`modx_site_tmplvar_contentvalues`.`contentid`
помогите как дальше сделатьвыборку из таблицы `modx_site_content` присоединив к ней значение доп.полей, код из таблицы `modx_site_tmplvar_contentvalues` с именем name = "code" в таблице `modx_site_tmplvars`
Вопрос: Помогите составить запрос выбрать n предыдущих строк с учётом ORDER BY

Уважаемые форумчане, помогите составить запрос.
Есть некоторый запрос типа SELECT * FROM table ORDER BY field.
В table есть колонка id.
Задано некоторое конкретное id( пусть равное 8)
нужно взять несколько строк из результата запроса, стоящих перед id=8.
field может быть составным, потому использовать его во WHERE нежелательно
Ответ:
RenusAvin
Уважаемые форумчане, помогите составить запрос.
Есть некоторый запрос типа SELECT * FROM table ORDER BY field.
В table есть колонка id.
Задано некоторое конкретное id( пусть равное 8)
нужно взять несколько строк из результата запроса, стоящих перед id=8.
field может быть составным, потому использовать его во WHERE нежелательно



приведите конкретный пример.
то у вас по ИД надо сортировать, то по какомутп "филду"
Вопрос: Как передавать параметры в рекурсивный запрос?

Например так
Select a, b as rec_z
From c

Я хочу чтобы можно было передать в рекурсивный запрос b,
значение a и результат запроса b зависел бы от a
Ответ:
den_alex_94
Например так
Select a, b as rec_z
From c

Я хочу чтобы можно было передать в рекурсивный запрос b,
значение a и результат запроса b зависел бы от a


звучит зловеще, главное не читать целиком :) но наверное про
Вопрос: Рекурсивный запрос

Здравствуйте.
имеются две таблицы.
data(id integer, name varchar(255))
и
data_links(upid integer, downid integer)

Вложенность может быть как на 1 уровень, так и на несколько.

Пробую сделать рекурсивный запрос:

WITH RECURSIVE tmp ( id, name, downid, upid ) AS (
SELECT d.id, d.name, d_l.downid, d_l.upid
    FROM data d
    join data_links d_l
    on d.id = d_l.upid
union
select d.id, d.name, d_l.downid, d_l.upid
from tmp t
join data_links d_l
on d_l.upid = t.downid
join data d
on d.id = d_l.downid
    
)
select tmp.* from tmp


Запрос работает, выводит все нормально.
Но мне требуется вернуть не все, а только данные самого верхнего уровня, и данные самого нижнего уровня
Получить в строку
data.id, data.name верхнего ууровня и data.id, data.name самого нижнего уровня
Данные верхнего уровня могут повторяться, так как одному значению верхнего уровня может соответствовать несколько значений самого нижнего уровня.
Как мне получить такие данные?
Ответ: Если не нужно соответствие Первый -> * -> Последний то достаточно такого запроса

    tOnlyUp as
     (select upid dataId from data_links --Все элементы на которые есть ссылка вверх
       except
      select downid from data_links -- и на них нет ссылки вниз
     ),
    tOnlyDown as 
     (select downid dataId from data_links 
       except
      select upid from data_links 
     ) tOnlyDown


если нужны только по цепочкам то скомбинируйте с Вашим рекурсивным запросом
Вопрос: Рекурсивный запрос (The maximum recursion 100)

Помогите с рекурсивным запросом.
Что делаю не так?

WITH deps AS
    (
        SELECT r.ID,
               ru.UserID,
               r.ParentID,
               r.TypeID
        FROM RoleUsers ru WITH (NOLOCK)
        INNER JOIN Roles r WITH(NOLOCK)
            ON r.ID = ru.ID
        INNER JOIN DepartmentRoles dr WITH(NOLOCK)
            ON dr.ID = r.ID
        WHERE ru.UserID = '3db19fa0-228a-497f-873a-0250bf0a4ccb'
        UNION ALL
        SELECT d.ID,
               d.UserID,
               d.ParentID,
               d.TypeID
        FROM deps d
        JOIN Roles r WITH(NOLOCK)
        ON r.ParentID = d.ID
    )
SELECT * FROM deps


Выдает 100 одинаковых строк и ошибку
[23000][530] The statement terminated. The maximum recursion 100 has been exhausted before statement completion.


Сообщение было отредактировано: 11 ноя 20, 13:45
Ответ: invm,

Оно!))
Спасибо!!!