Помощ за sql заявка

19 отговора 0 прегледа
#1

Помощ за 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

Редактирано от todor68O8 на

Отговор
в отговор на todor68O8 #2

Re: Помощ за sql заявка

Май ще е нещо такова

SELECT *
FROM classes
WHERE parent_name = any(SELECT id_name FROM classes)

Редактирано от todor68O8 на

Отговор
в отговор на todor68O8 #3

Re: Помощ за sql заявка

Ако MySQL поддържа Common Table Extensions ще стане относително лесно. Иначе за тази йерархия трябва цикъл някой да върти -- клиентския код или със SQL.

cheers,
</wqw>

[линк]
Отговор
в отговор на todor68O8 #4

Re: Помощ за sql заявка

Межу другото идеята да съхраняваш стойности като x:y не е никак добра поради много причини.

Ако това са истинските данни частта "1:" е напълно излишна. Ако не са то тогава разбий въпросната двойка x:y на две колонки.

salle.online.bg/sig
Отговор
в отговор на todor68O8 #5

Re: Помощ за sql заявка

Дефинирай "равни на предишното id_name" и ще се сетиш как става. Не забравяй обаче, че ти трябва ORDER BY клауза. Без нея сървърът е свободен да ти върне резултата в произволен ред.

salle.online.bg/sig
Отговор
в отговор на salle #6

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 - е номера на родителя към който принадлежи

Другите колони са за различни стойности

Та въпроса е как да се сортира таблицата та да се наредят класовете подредени, с техните под класове.

И ако изтърка един клас как да се изтъркат всички негови под класове.

Абе опашата задача

Редактирано от todor68O8 на

Отговор
в отговор на salle #7

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
Отговор
в отговор на todor68O8 #8

Re: Помощ за sql заявка

"Та въпроса е как да се сортира таблицата та да се наредят класовете подредени, с техните под класове. "

SELECT ... ORDER BY id, parent_id;

salle.online.bg/sig

Редактирано от salle на

Отговор
в отговор на salle #9

Re: Помощ за sql заявка

така де, обратното parent_id, id :)

salle.online.bg/sig
Отговор
в отговор на salle #10

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
Отговор
в отговор на salle #11

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

Задължен съм ти с няколко бири.

Редактирано от todor68O8 на

Отговор
в отговор на todor68O8 #12

Re: Помощ за sql заявка

Като цяло имаш добре известен проблем.

Йерархичните данни и Релационния модел трудно се понасят поради несъвместимости на теоретично ниво. В MySQL няма никакви йерархични функции така, че трябва сам да ги напиишеш или в приложението или като stored procedures/functions

Една колекция от полезни връзки по въпроса:

[линк]

За DELETE всъщност ти върши работа помогне FOREIGN KEY .. ON DELETE CASCADE, но таблицата трябва да е InnoDB и да дефинираш коренов клас, който си е родител сам на себе си иначе няма да стане.

А за Чепеларе ... все не ми остава време да му се не види ...

salle.online.bg/sig
Отговор
в отговор на salle #13

Re: Помощ за sql заявка

Това страшно ми помогна
[линк]

Може да се добавя, трие, единствено не видяш
как е направено ако трябва да се премести даден клас към някой друг.
т.е. премествайки го да повлече и свойте деца с него.

Между другото ето една реализация на nested set model под php5
[линк]


Едно голямо благодаря

Редактирано от todor68O8 на

Отговор
в отговор на todor68O8 #14

Re: Помощ за sql заявка

Местенето е най-лесната част - сменяш само parent - и си преместил всичко.
В смисъл както е даден примера портабле електроникс е дете на електроникс - и като му смениш парент на 2 става дете на телевизорите - заедно с всички негови деца...

Bеer? Mоre?
Плацебото
Отговор
в отговор на bira_more #15

Re: Помощ за sql заявка

При nested set model положението в ерархията се определя от lft и rgt
променливите



Отговор
в отговор на todor68O8 #16

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>

[линк]
Отговор
в отговор на wqw #17

Re: Помощ за sql заявка

"Ако MySQL реализират CTE от последните стандарти на SQL скоро ще може ..."

Няма такива планове в обозримо бъдеще.

salle.online.bg/sig
Отговор
в отговор на todor68O8 #18

Re: Помощ за sql заявка

Тук има описана реализация с тригери и сторед процедури. Не е на MySql, но важен е принципа.
А за описание на класове в RDBMS добра статия е ООП и RDBMS

Редактирано от NDeu на

Отговор
в отговор на NDeu #19

Re: Помощ за sql заявка

Направиш го благодаря на всички.

А който иска да го тегли поблукуваш го в [линк]

Отговор
в отговор на todor68O8 #20

Re: Помощ за sql заявка

Not bad

[линк]
Отговор