Помощ за sql заявка
19 отговора
0 прегледа
Помощ за sql заявка
Ако може малко помощ за следната SQL заявка.
Имам таблица под MySQL - 5.0.32-Debian_7etch10-log
CREATE TABLE `classes` (
`id` int(4) NOT NULL auto_increment,
`id_name` varchar(20) NOT NULL,
`parent_name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=184 ;
id_name | parent_name
-------------------------------
1:1 | 0
1:32 | 1:1
1:33 | 1:1
1:34 | 1:32
1:35 | 1:32
1:36 | 1:33
1:37 | 1:34
1:39 | 1:1
1:40 | 1:1
...
</pre></font>
Ta каква заявка да направя че таблицата да ми излиза в този вид
id_name | parent_name
-------------------------------
1:1 | 0
1:32 | 1:1
1:34 | 1:32
1:35 | 1:32
1:37 | 1:34
1:33 | 1:1
1:36 | 1:33
1:39 | 1:1
1:40 | 1:1
....
т.е. да се сортира първо колона id_name, и след това всички parent_name които са равни на придишното id_name
Имам таблица под MySQL - 5.0.32-Debian_7etch10-log
CREATE TABLE `classes` (
`id` int(4) NOT NULL auto_increment,
`id_name` varchar(20) NOT NULL,
`parent_name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=184 ;
id_name | parent_name
-------------------------------
1:1 | 0
1:32 | 1:1
1:33 | 1:1
1:34 | 1:32
1:35 | 1:32
1:36 | 1:33
1:37 | 1:34
1:39 | 1:1
1:40 | 1:1
...
</pre></font>
Ta каква заявка да направя че таблицата да ми излиза в този вид
id_name | parent_name
-------------------------------
1:1 | 0
1:32 | 1:1
1:34 | 1:32
1:35 | 1:32
1:37 | 1:34
1:33 | 1:1
1:36 | 1:33
1:39 | 1:1
1:40 | 1:1
....
т.е. да се сортира първо колона id_name, и след това всички parent_name които са равни на придишното id_name
Редактирано от todor68O8 на
Re: Помощ за sql заявка
Май ще е нещо такова
SELECT *
FROM classes
WHERE parent_name = any(SELECT id_name FROM classes)
SELECT *
FROM classes
WHERE parent_name = any(SELECT id_name FROM classes)
Редактирано от todor68O8 на
Re: Помощ за sql заявка
Ако MySQL поддържа Common Table Extensions ще стане относително лесно. Иначе за тази йерархия трябва цикъл някой да върти -- клиентския код или със SQL.
cheers,
</wqw>
[линк]
cheers,
</wqw>
[линк]
Re: Помощ за sql заявка
Межу другото идеята да съхраняваш стойности като x:y не е никак добра поради много причини.
Ако това са истинските данни частта "1:" е напълно излишна. Ако не са то тогава разбий въпросната двойка x:y на две колонки.
salle.online.bg/sig
Ако това са истинските данни частта "1:" е напълно излишна. Ако не са то тогава разбий въпросната двойка x:y на две колонки.
salle.online.bg/sig
Re: Помощ за sql заявка
Дефинирай "равни на предишното id_name" и ще се сетиш как става. Не забравяй обаче, че ти трябва ORDER BY клауза. Без нея сървърът е свободен да ти върне резултата в произволен ред.
salle.online.bg/sig
salle.online.bg/sig
Re: Помощ за sql заявка
Цялата задачата дойде от това че искам да направя web базиран интерфейс на tc-htb
[линк]
Там най-общо се работи с класове който имат свой родители и свой деца, най образно казано
И всеки клас може да има също свой под класове
Приемам че най добре е да има колона родител /да е наречем id), и колона дете(да е наречем id_parent)
и тука възникна въпроса с mysql заявките
Но мисля че донякъде се справиш:
SELECT PARENT.name AS 'Root-Class', CHILD.name AS 'Child-Class', CHILD.rate AS Rate, CHILD.ceil AS Ceil, CHILD.burst AS Burst, CHILD.prio AS Prio, CHILD.monitor AS Monitor
FROM classes AS PARENT, classes AS CHILD
WHERE PARENT.id = CHILD.id_parent
AND PARENT.id_interfaces =10
таблица: classes
CREATE TABLE `classes` (
`id` int(4) NOT NULL auto_increment,
`id_interfaces` int(3) NOT NULL,
`name` varchar(254) NOT NULL,
`leaf` varchar(3) NOT NULL default 'sfq',
`rate` varchar(20) NOT NULL,
`ceil` varchar(20) NOT NULL,
`burst` varchar(10) default NULL,
`prio` varchar(1) NOT NULL default '3',
`id_parent` int(4) NOT NULL,
`monitor` int(1) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=184 ;
id - e уникалния номер на класа
id_parent - е номера на родителя към който принадлежи
Другите колони са за различни стойности
Та въпроса е как да се сортира таблицата та да се наредят класовете подредени, с техните под класове.
И ако изтърка един клас как да се изтъркат всички негови под класове.
Абе опашата задача
[линк]
Там най-общо се работи с класове който имат свой родители и свой деца, най образно казано
И всеки клас може да има също свой под класове
Приемам че най добре е да има колона родител /да е наречем id), и колона дете(да е наречем id_parent)
и тука възникна въпроса с mysql заявките
Но мисля че донякъде се справиш:
SELECT PARENT.name AS 'Root-Class', CHILD.name AS 'Child-Class', CHILD.rate AS Rate, CHILD.ceil AS Ceil, CHILD.burst AS Burst, CHILD.prio AS Prio, CHILD.monitor AS Monitor
FROM classes AS PARENT, classes AS CHILD
WHERE PARENT.id = CHILD.id_parent
AND PARENT.id_interfaces =10
таблица: classes
CREATE TABLE `classes` (
`id` int(4) NOT NULL auto_increment,
`id_interfaces` int(3) NOT NULL,
`name` varchar(254) NOT NULL,
`leaf` varchar(3) NOT NULL default 'sfq',
`rate` varchar(20) NOT NULL,
`ceil` varchar(20) NOT NULL,
`burst` varchar(10) default NULL,
`prio` varchar(1) NOT NULL default '3',
`id_parent` int(4) NOT NULL,
`monitor` int(1) NOT NULL default '0',
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=184 ;
id - e уникалния номер на класа
id_parent - е номера на родителя към който принадлежи
Другите колони са за различни стойности
Та въпроса е как да се сортира таблицата та да се наредят класовете подредени, с техните под класове.
И ако изтърка един клас как да се изтъркат всички негови под класове.
Абе опашата задача
Редактирано от todor68O8 на
Re: Помощ за sql заявка
Да поясня. Като казваш "равни на предишното" не стават ясни много неща.
Преишното по какъв признак? Да речем, че говорим за поредица от числа. Има съществена разлика дали поредицате е непрекъстната.
Предишното на 5 например 4 ли е или "най-голямото число по-малко от 4"
Освен това от структурата на таблицата ти следва, че може да има повторения в поредицата т.е. да имаш 1,2,3,4,4,5. В този случай кое е "предишното на 5"? Ако става въпрос само за сортиране не е проблем разбира се да сортилаш двете четворки заедно.
И разбира се използвай INT
Ето един пример за дървовидна структура. Дефиницията на таблицата определя, че всеки елемент има само един "родител", но може да има много "наследници"
CREATE TABLE `class` (
`id` int(10) unsigned NOT NULL auto_increment,
`parent_id` int(10) unsigned default NULL,
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`)
);
INSERT INTO class (parent_id) VALUES (0), (1), (2), (3), (1);
До сортираме по id и parent_id поотделно:
SELECT * FROM class ORDER BY id;
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 1 |
+----+-----------+
SELECT * FROM class ORDER BY parent_id;
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 0 |
| 2 | 1 |
| 5 | 1 |
| 3 | 2 |
| 4 | 3 |
+----+-----------+
Кажи сега при този резултат как да дефинираме задачката.
salle.online.bg/sig
Преишното по какъв признак? Да речем, че говорим за поредица от числа. Има съществена разлика дали поредицате е непрекъстната.
Предишното на 5 например 4 ли е или "най-голямото число по-малко от 4"
Освен това от структурата на таблицата ти следва, че може да има повторения в поредицата т.е. да имаш 1,2,3,4,4,5. В този случай кое е "предишното на 5"? Ако става въпрос само за сортиране не е проблем разбира се да сортилаш двете четворки заедно.
И разбира се използвай INT
Ето един пример за дървовидна структура. Дефиницията на таблицата определя, че всеки елемент има само един "родител", но може да има много "наследници"
CREATE TABLE `class` (
`id` int(10) unsigned NOT NULL auto_increment,
`parent_id` int(10) unsigned default NULL,
PRIMARY KEY (`id`),
KEY `parent_id` (`parent_id`)
);
INSERT INTO class (parent_id) VALUES (0), (1), (2), (3), (1);
До сортираме по id и parent_id поотделно:
SELECT * FROM class ORDER BY id;
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 0 |
| 2 | 1 |
| 3 | 2 |
| 4 | 3 |
| 5 | 1 |
+----+-----------+
SELECT * FROM class ORDER BY parent_id;
+----+-----------+
| id | parent_id |
+----+-----------+
| 1 | 0 |
| 2 | 1 |
| 5 | 1 |
| 3 | 2 |
| 4 | 3 |
+----+-----------+
Кажи сега при този резултат как да дефинираме задачката.
salle.online.bg/sig
Re: Помощ за sql заявка
"Та въпроса е как да се сортира таблицата та да се наредят класовете подредени, с техните под класове. "
SELECT ... ORDER BY id, parent_id;
salle.online.bg/sig
SELECT ... ORDER BY id, parent_id;
salle.online.bg/sig
Редактирано от salle на
Re: Помощ за sql заявка
Ето го и примера за "подредени с техните подкласове"
SELECT c1.id parent, c2.id child FROM class c1 LEFT JOIN class c2 ON c1.id = c2.parent_id ORDER BY c1.id, c2.id;
salle.online.bg/sig
SELECT c1.id parent, c2.id child FROM class c1 LEFT JOIN class c2 ON c1.id = c2.parent_id ORDER BY c1.id, c2.id;
salle.online.bg/sig
Re: Помощ за sql заявка
Първо благодаря ти много.
Малко са хората който като теб който не си щадят времето.
И извинявам се, че не конкретизирах доста моята задача.
Ето какво трябва да направя,
С няколко изречения предварително.
Linux използва за трафик контрол инструмента tc и искам да направя еднин php+mysql frontend който да рисува тези правила.
Ето и един пример.
Това е първия родителски клас:
class htb 1:1 root rate 100000Kbit ceil 100000Kbit burst 3200b cburst 1600b
Следващия клас с индификатор 46 и подклас на клас 1:1
class htb 1:46 parent 1:1 leaf 46: prio 3 rate 256000bit ceil 256000bit burst 255b cburst 1599b
Следващия клас с индификатор 47 и подклас на клас 1:1
class htb 1:47 parent 1:1 leaf 47: rate 100000Kbit ceil 100000Kbit burst 237b cburst 1600b
Следващия клас с индификатор 48 и подклас на клас 1:47
class htb 1:48 parent 1:47 leaf 48: prio 3 rate 80000Kbit ceil 80000Kbit burst 240b cburst 1590b
Следващия клас с индификатор 49 и подклас на клас 1:48
class htb 1:49 parent 1:47 leaf 49: prio 3 rate 20000Kbit ceil 20000Kbit burst 252b cburst 1600b
От този целия синтаксис искам да организирам подредбата на класовете
тези които са подчертани и да ги вкарам в MySQL таблица.
Ясно се вижда че това е една ерархична структура подредени като класове и под класове. Като всеки клас има уникален индификатор за класа и индификатор за родителя.
Но при изплънение е важно първо да се изпълни първи родителския клас и след това всички под класове.
Като всеки клас може да има 1 родител, а той много под класове.
Но мисля че вече се орентирам.
Пълненето на таблицата няма да е проблем, (е и тук трябжа да се следи кой е родителя) но важното е след като се напълни, да се изпълняват командите в ред който указах.
И не на последно место какво ще представлява клаузата DELETE.
т.е. Ако се изтрие един клас как да се изтрият неговите под класове.
Като голяма вероятност е той да е с дълбочина n-на брой
Като родителството може да е n-на брой дълбочина.
Абе нали ти казаш опашата задача.
Но още веднаш благодаря.
Пък ако минаваш през Чепеларе обаждай се ... питай за Тодор
Навремето преди 7-8 години се видяхме на един Linux-fest
Задължен съм ти с няколко бири.
Малко са хората който като теб който не си щадят времето.
И извинявам се, че не конкретизирах доста моята задача.
Ето какво трябва да направя,
С няколко изречения предварително.
Linux използва за трафик контрол инструмента tc и искам да направя еднин php+mysql frontend който да рисува тези правила.
Ето и един пример.
Това е първия родителски клас:
class htb 1:1 root rate 100000Kbit ceil 100000Kbit burst 3200b cburst 1600b
Следващия клас с индификатор 46 и подклас на клас 1:1
class htb 1:46 parent 1:1 leaf 46: prio 3 rate 256000bit ceil 256000bit burst 255b cburst 1599b
Следващия клас с индификатор 47 и подклас на клас 1:1
class htb 1:47 parent 1:1 leaf 47: rate 100000Kbit ceil 100000Kbit burst 237b cburst 1600b
Следващия клас с индификатор 48 и подклас на клас 1:47
class htb 1:48 parent 1:47 leaf 48: prio 3 rate 80000Kbit ceil 80000Kbit burst 240b cburst 1590b
Следващия клас с индификатор 49 и подклас на клас 1:48
class htb 1:49 parent 1:47 leaf 49: prio 3 rate 20000Kbit ceil 20000Kbit burst 252b cburst 1600b
От този целия синтаксис искам да организирам подредбата на класовете
тези които са подчертани и да ги вкарам в MySQL таблица.
Ясно се вижда че това е една ерархична структура подредени като класове и под класове. Като всеки клас има уникален индификатор за класа и индификатор за родителя.
Но при изплънение е важно първо да се изпълни първи родителския клас и след това всички под класове.
Като всеки клас може да има 1 родител, а той много под класове.
Но мисля че вече се орентирам.
Пълненето на таблицата няма да е проблем, (е и тук трябжа да се следи кой е родителя) но важното е след като се напълни, да се изпълняват командите в ред който указах.
И не на последно место какво ще представлява клаузата DELETE.
т.е. Ако се изтрие един клас как да се изтрият неговите под класове.
Като голяма вероятност е той да е с дълбочина n-на брой
Като родителството може да е n-на брой дълбочина.
Абе нали ти казаш опашата задача.
Но още веднаш благодаря.
Пък ако минаваш през Чепеларе обаждай се ... питай за Тодор
Навремето преди 7-8 години се видяхме на един Linux-fest
Задължен съм ти с няколко бири.
Редактирано от todor68O8 на
Re: Помощ за sql заявка
Като цяло имаш добре известен проблем.
Йерархичните данни и Релационния модел трудно се понасят поради несъвместимости на теоретично ниво. В MySQL няма никакви йерархични функции така, че трябва сам да ги напиишеш или в приложението или като stored procedures/functions
Една колекция от полезни връзки по въпроса:
[линк]
За DELETE всъщност ти върши работа помогне FOREIGN KEY .. ON DELETE CASCADE, но таблицата трябва да е InnoDB и да дефинираш коренов клас, който си е родител сам на себе си иначе няма да стане.
А за Чепеларе ... все не ми остава време да му се не види ...
salle.online.bg/sig
Йерархичните данни и Релационния модел трудно се понасят поради несъвместимости на теоретично ниво. В MySQL няма никакви йерархични функции така, че трябва сам да ги напиишеш или в приложението или като stored procedures/functions
Една колекция от полезни връзки по въпроса:
[линк]
За DELETE всъщност ти върши работа помогне FOREIGN KEY .. ON DELETE CASCADE, но таблицата трябва да е InnoDB и да дефинираш коренов клас, който си е родител сам на себе си иначе няма да стане.
А за Чепеларе ... все не ми остава време да му се не види ...
salle.online.bg/sig
Re: Помощ за sql заявка
Това страшно ми помогна
[линк]
Може да се добавя, трие, единствено не видяш
как е направено ако трябва да се премести даден клас към някой друг.
т.е. премествайки го да повлече и свойте деца с него.
Между другото ето една реализация на nested set model под php5
[линк]
Едно голямо благодаря
[линк]
Може да се добавя, трие, единствено не видяш
как е направено ако трябва да се премести даден клас към някой друг.
т.е. премествайки го да повлече и свойте деца с него.
Между другото ето една реализация на nested set model под php5
[линк]
Едно голямо благодаря
Редактирано от todor68O8 на
Re: Помощ за sql заявка
Местенето е най-лесната част - сменяш само parent - и си преместил всичко.
В смисъл както е даден примера портабле електроникс е дете на електроникс - и като му смениш парент на 2 става дете на телевизорите - заедно с всички негови деца...
Bеer? Mоre?
Плацебото
В смисъл както е даден примера портабле електроникс е дете на електроникс - и като му смениш парент на 2 става дете на телевизорите - заедно с всички негови деца...
Bеer? Mоre?
Плацебото
Re: Помощ за sql заявка
При nested set model положението в ерархията се определя от lft и rgt
променливите
променливите
Re: Помощ за sql заявка
Значи все пак реши да въртиш цикъла в клиента (PHP). Поддръжката на nested set модела не е особено евтина, т.е. ще се бави при добавяне, триене и местене, за сметка на това SELECT-ите ще са светкавични.
Ако MySQL реализират CTE от последните стандарти на SQL скоро ще може да се работи с adjacency list-ове (оригиналният ти модел с parent) без "подкрепа" от клиентския код.
Иначе това което търсеше щеше да стане като конструираш колона Path в която да налееш пътя през parent-а до корена. На финала идеята е да направиш ORDER BY Path т.е. Path трябва да е "удобна" за тази цел. Например id-та на пътя нагоре pad-ната с нули отляво до 5 символа т.е. нещо като '000010000500012'.
Btw, ако денормализираш подобна колона в base таблицата повечето от екстрите на nested set можеш да направиш със нея само. Самото поддържане на тази колона не е по-евтино от nested set обаче.
cheers,
</wqw>
[линк]
Ако MySQL реализират CTE от последните стандарти на SQL скоро ще може да се работи с adjacency list-ове (оригиналният ти модел с parent) без "подкрепа" от клиентския код.
Иначе това което търсеше щеше да стане като конструираш колона Path в която да налееш пътя през parent-а до корена. На финала идеята е да направиш ORDER BY Path т.е. Path трябва да е "удобна" за тази цел. Например id-та на пътя нагоре pad-ната с нули отляво до 5 символа т.е. нещо като '000010000500012'.
Btw, ако денормализираш подобна колона в base таблицата повечето от екстрите на nested set можеш да направиш със нея само. Самото поддържане на тази колона не е по-евтино от nested set обаче.
cheers,
</wqw>
[линк]
Re: Помощ за sql заявка
"Ако MySQL реализират CTE от последните стандарти на SQL скоро ще може ..."
Няма такива планове в обозримо бъдеще.
salle.online.bg/sig
Няма такива планове в обозримо бъдеще.
salle.online.bg/sig
Re: Помощ за sql заявка
Тук има описана реализация с тригери и сторед процедури. Не е на MySql, но важен е принципа.
А за описание на класове в RDBMS добра статия е ООП и RDBMS
А за описание на класове в RDBMS добра статия е ООП и RDBMS
Редактирано от NDeu на
Re: Помощ за sql заявка
Направиш го благодаря на всички.
А който иска да го тегли поблукуваш го в [линк]
А който иска да го тегли поблукуваш го в [линк]