Хитрый SQL запрос в MySQL (Проблема вторая)

Модератор: Модераторы разделов

SatanaClause
Сообщения: 106

Хитрый SQL запрос в MySQL

Сообщение SatanaClause »

Вернемся, так сказать, к нашим баранам

Есть таблица например

Код: Выделить всё

CREATE TABLE `gs_udb_mb` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `ports` varchar(255) default '',
  PRIMARY KEY  (`id`)
);


В ней есть записи следующего вида

Код: Выделить всё

INSERT INTO `gs_udb_mb` VALUES (2,'14|15|43|70');


14|15|43|70 - это ид из таблицы `gs_udb_static`.

Код: Выделить всё

CREATE TABLE `gs_udb_static` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `group` varchar(255) NOT NULL default '',
  `text` varchar(255) NOT NULL default '',
  `comment` text NOT NULL,
  `status` int(1) default '1',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=19;

INSERT INTO `gs_udb_static` VALUES (1, 'g_NC_speed', '10/100 Mbt/s', '', 1);
INSERT INTO `gs_udb_static` VALUES (2, 'g_NC_speed', '10 Mbt/s', '', 1);
INSERT INTO `gs_udb_static` VALUES (17, 'g_NC_company', 'Compex', '', 1);
INSERT INTO `gs_udb_static` VALUES (4, 'g_WHO', 'Alan Vezhbitskis', '', 1);
INSERT INTO `gs_udb_static` VALUES (5, 'g_WHO', 'Jurij Burlov', '', 1);
INSERT INTO `gs_udb_static` VALUES (6, 'g_WHO', 'Romualdas Jokubavičius', '', 1);
INSERT INTO `gs_udb_static` VALUES (12, 'g_WHERE', 'Mokykla 513', '', 1);
INSERT INTO `gs_udb_static` VALUES (13, 'g_WHERE', 'Mokykla 013', '', 1);
INSERT INTO `gs_udb_static` VALUES (14, 'g_NC_slot', 'ISA', '', 1);
INSERT INTO `gs_udb_static` VALUES (15, 'g_NC_slot', 'PCI', '', 1);
INSERT INTO `gs_udb_static` VALUES (16, 'g_NC_company', 'Realtek', '', 1);
INSERT INTO `gs_udb_static` VALUES (18, 'g_NC_chip', 'RTL8029', '', 1);


Собственно говоря проблема заключается в том что мне надо реализовать выборку по этим ид и поиск. Примерно суть такая

Код: Выделить всё

SELECT static.* FROM gs_udb_mb as mb, gs_udb_static as static WHERE static.id=mb.ports


Вот тут static.id=mb.ports и заключается проблема, я нашел функцию которая обединяет записи, CONCAT_WS (чтото типо implode), но некак немогу допереть как потом разбить строку обратно, функции типо explode я ненашел. Пробывал сделать это при помощи ELT() и FIELD() но немогу допереть как органицовать цикл...

Скорее всего я чтото пропустил...
Я люблю людей, люблю когда их нет;
Я бы вышел на болкон, и разрядил бы пистолет!
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Хитрый SQL запрос в MySQL

Сообщение serzh-z »

Написать хранимую процедуру, которая будет разбивать строку и возвращать ее в виде таблицы (не уверен, что в MySQL возможно такое - если же нет, то упомянутая процедура просто должна будет складывать результат во временную таблицу с известным именем).

В итоге все должно будет свестить к примерно следующему:

select * from gs_udb_static where id in(select split_string(ports, '|') from (select ports from gs_udb_m));

Не проверял, но думаю, что идея понятна - если нужно одними средствами SQL, то без процедур никак.
Спасибо сказали:
SatanaClause
Сообщения: 106

Re: Хитрый SQL запрос в MySQL

Сообщение SatanaClause »

наверно будет рационельнее разбить запрос на две части, или я ошибаюсь?
Я люблю людей, люблю когда их нет;
Я бы вышел на болкон, и разрядил бы пистолет!
Спасибо сказали:
miron
Сообщения: 25
ОС: SlackWare Linux 10.2

Re: Хитрый SQL запрос в MySQL

Сообщение miron »

А мне кажеться логичней было бы не пихать в одно поле "ports" все порты, а для каждого порта отдельную запись и ключ в таблице сделать такой primary key('id','port')
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Хитрый SQL запрос в MySQL

Сообщение serzh-z »

miron писал(а):
10.11.2006 10:06
А мне кажеться логичней было бы не пихать в одно поле "ports" все порты, а для каждого порта отдельную запись и ключ в таблице сделать такой primary key('id','port')
:) Почему-то мне кажется, что это автор не от хорошей жизни решил заниматься таким извращением. Надо полагать, что софт (или другая часть кода), который помещает в БД номера портов в таком виде тоже ведь потребует рефакторинга.
Спасибо сказали:
miron
Сообщения: 25
ОС: SlackWare Linux 10.2

Re: Хитрый SQL запрос в MySQL

Сообщение miron »

serzh-z писал(а):
10.11.2006 11:15
miron писал(а):
10.11.2006 10:06

А мне кажеться логичней было бы не пихать в одно поле "ports" все порты, а для каждого порта отдельную запись и ключ в таблице сделать такой primary key('id','port')
:) Почему-то мне кажется, что это автор не от хорошей жизни решил заниматься таким извращением. Надо полагать, что софт (или другая часть кода), который помещает в БД номера портов в таком виде тоже ведь потребует рефакторинга.


Лучше сразу написать нормально чем потом долго мучиться и все равно переписать нормально... :)
Спасибо сказали:
SatanaClause
Сообщения: 106

Re: Хитрый SQL запрос в MySQL

Сообщение SatanaClause »

Все гораздо бональнее, таблица mb это таблица материнских плат, помимо ports там еще около 20 полей с разными критериями материнских плат (и они постоянно прибовляются по мере надобности). В данном случае под понятием порты подразумивается com, lpt, usb... если я буду все так расписывать то таблица расползется в ширь до невероятных размеров, плюс ко всему этому количество елементов динамичиски меняется. Вот например запись из статик, это щначит что в таблицы сетевых карт будет два значения из которыз можно выбрать.

Код: Выделить всё

INSERT INTO `gs_udb_static` VALUES (14, 'g_NC_slot', 'ISA', '', 1);
INSERT INTO `gs_udb_static` VALUES (15, 'g_NC_slot', 'PCI', '', 1);


Есть поля где таких значений около 100, вот мне и пришлось обединить некоторые значения таким способом. В программе это просто chekbox'ы, и такой вид записи меня полностю устраивает.

Изображение

это еще небольшая таблица, есть раза в три больше, так что делать на каждый чекбокс по полю неудобно.
Я люблю людей, люблю когда их нет;
Я бы вышел на болкон, и разрядил бы пистолет!
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Хитрый SQL запрос в MySQL

Сообщение serzh-z »

А сборщик форм не может некоторые поля отобразить графически более компактно?
Спасибо сказали:
miron
Сообщения: 25
ОС: SlackWare Linux 10.2

Re: Хитрый SQL запрос в MySQL

Сообщение miron »

Учитывая вашу задачу, я бы спроектировал базу так....
В таблице с материнками только общая информация...
Создать таблицу с типами деталей (слоты. порты. шины)
Например
1 Порты
2 Память
3 Шины
4 Слоты
и т.д.
И таблицу связки со структурой чтото вроде
Id(материнской платы) Id(из таблицы выше) Id(соответствующей детали из справочника, соответсвующего Id из второй колонки)
Спасибо сказали:
SatanaClause
Сообщения: 106

Re: Хитрый SQL запрос в MySQL

Сообщение SatanaClause »

serzh-z писал(а):
10.11.2006 16:49
А сборщик форм не может некоторые поля отобразить графически более компактно?

всмысли более компактно? в несколько рядов? Это все еще только отрабатывается и меняется, внешнем видом потом займусь, это не столь сейчас важно. Я много времени потратин на написания класса для построения форм и таблиц, вот теперь думаю как неугрохать столько же в таблицы.

Так как посаветуете, не мучатся и разбить на два запроса, или всетаки процедуру делать? Проблема еще в том что я использую adodb (про этот класс в первой теме "хитрые SQL запросы") так вот там тоже есть некоторые ограничения, например один из видов базы данные это просто текстовые файлы, так вот там точно непройдет фокус с процедурами, сомниваюсь что JOIN будет работать... Я с помошью этого класа переделывал форум phpbb с mysql на файлы (по принципу как работает limbo, клон mamboserver'a) но там sql синтаксис простой.

Вот такая вот делема, вообще странно, стандартная функция, которая записывает в такой формат (11|22|33|44) есть, а обратно нету, не логично!

miron писал(а):
10.11.2006 17:59
Учитывая вашу задачу, я бы спроектировал базу так....
В таблице с материнками только общая информация...
Создать таблицу с типами деталей (слоты. порты. шины)
Например
1 Порты
2 Память
3 Шины
4 Слоты
и т.д.
И таблицу связки со структурой чтото вроде
Id(материнской платы) Id(из таблицы выше) Id(соответствующей детали из справочника, соответсвующего Id из второй колонки)

а вы предстовляете сколько тогда таких таблиц будет, кроме материнской платы есть еще сетевая карта, память, видео, звук, тюнеры... к которым нужно еще дополнительные поля... одних таблиц за сотню перевалит.
Я люблю людей, люблю когда их нет;
Я бы вышел на болкон, и разрядил бы пистолет!
Спасибо сказали:
miron
Сообщения: 25
ОС: SlackWare Linux 10.2

Re: Хитрый SQL запрос в MySQL

Сообщение miron »

Учитывая ваше высказывание
>Все гораздо бональнее, таблица mb это таблица материнских плат...
я подумал что так оно и есть как вы написали в последнем посте :)
Спасибо сказали:
Аватара пользователя
serzh-z
Бывший модератор
Сообщения: 8259
Статус: Маньяк
ОС: Arch, Fedora, Ubuntu

Re: Хитрый SQL запрос в MySQL

Сообщение serzh-z »

Хранение в одной ячейке таблицы нескольких значений противоречит правилам построения реляционной БД. То есть таблица не соответствует даже первой нормальной форме. И это не есть хорошо.

Если система делается с нуля, то сделайте уж лучше, как miron советовал.
Спасибо сказали:
miron
Сообщения: 25
ОС: SlackWare Linux 10.2

Re: Хитрый SQL запрос в MySQL

Сообщение miron »

serzh-z писал(а):
10.11.2006 18:18
Хранение в одной ячейке таблицы нескольких значений противоречит правилам построения реляционной БД. То есть таблица не соответствует даже первой нормальной форме. B это не есть хорошо.

Если уж система делается с нуля, то сделайте уж лучше, как miron советовал.


+1 Я только хотел написать, чтоб человек почитал про нормализацию :)
Спасибо сказали:
SatanaClause
Сообщения: 106

Re: Хитрый SQL запрос в MySQL

Сообщение SatanaClause »

miron писал(а):
10.11.2006 18:20
+1 Я только хотел написать, чтоб человек почитал про нормализацию :)

Знаю я и про стандарты и про реляционные бд. к сожалению это только один модуль одной большой системы, которая уже функционирует.

Значит буду разбивать запрос на две части. Всем спасибо!
Я люблю людей, люблю когда их нет;
Я бы вышел на болкон, и разрядил бы пистолет!
Спасибо сказали:
Аватара пользователя
sarutobi
Сообщения: 676
Статус: Добрость и скромнота
ОС: Debian 5, FreeBSD 6.2/8.0

Re: Хитрый SQL запрос в MySQL

Сообщение sarutobi »

А почему бы Вам не сделать таблицу такой структуры:

Код: Выделить всё

CREATE TABLE `gs_udb_mb` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `mb_id` int (10) not null
  `ports` int(10) not null,
  PRIMARY KEY  (`id`)
);

ИМХО Ваша проблема решается автоматом. Или я чего то не учел?
Fire and water, earth and sky - mistery surrounds us, legends never die!
Спасибо сказали:
SatanaClause
Сообщения: 106

Re: Хитрый SQL запрос в MySQL

Сообщение SatanaClause »

sarutobi писал(а):
10.11.2006 21:02
А почему бы Вам не сделать таблицу такой структуры:

Код: Выделить всё

CREATE TABLE `gs_udb_mb` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `mb_id` int (10) not null
  `ports` int(10) not null,
  PRIMARY KEY  (`id`)
);

ИМХО Ваша проблема решается автоматом. Или я чего то не учел?


все логично, не спорю, и правильнее, чем я сейчас сделал. Но таких таблиц надо будет создать очень много. А это неудобно. Да и основная информация уже вводится с другой программы в таком виде 11|22|33. То что я делаю это только интерфейс для удаленного администрирования.
Я люблю людей, люблю когда их нет;
Я бы вышел на болкон, и разрядил бы пистолет!
Спасибо сказали: