Сложный запрос MySQL из PHP.

sky19

Новичок
Сложный запрос MySQL из PHP.

Приветствую всех!

У меня в базе есть записи с перечислением цифр, типа "1,4,6,19" и т.п.

Стоит задача: послать запрос и выбрать все записи содержащие, например "1" (но не "1" в составе цифры девятнадцать").

Понятно, что это можно разобрать уже на уровне PHP, разбить в массив запятыми и массив уже сравнивать, но есть ли возможность сделать это на уровне запроса в MySQL?
 

tony2001

TeaM PHPClub
переделай структуру таблиц на один-ко-многим, так делать не надо.
 

ixti

Новичок
Как вариант, если нет уже возможности или крайне сложно изменить структуру таблиц...

Создаем примерную таблицу

DROP TABLE IF EXISTS `200503310955`;
CREATE TABLE `test` (
`Id` int(11) NOT NULL auto_increment,
`Numbers` int(11) default NULL,
PRIMARY KEY (`Id`)
) TYPE=MyISAM;


Вставляем данные

INSERT INTO `test` (`Id`,`Numbers`) VALUES (1,1);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (2,4);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (3,6);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (4,12);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (5,19);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (6,318);


Выполняем запрос

SELECT * FROM `test` WHERE `Numbers` LIKE '%1%' AND `Numbers` != 12


Результат выполнения
Код:
+----+---------+
| Id | Numbers |
+----+---------+
|  1 |       1 |
|  3 |       19|
|  6 |      318|
+----+---------+
3 rows in set (0.00 sec)
 

Kane

Новичок
Re: Как вариант, если нет уже возможности или крайне сложно изменить структуру таблиц

Автор оригинала: ixti
Создаем примерную таблицу

DROP TABLE IF EXISTS `200503310955`;
CREATE TABLE `test` (
`Id` int(11) NOT NULL auto_increment,
`Numbers` int(11) default NULL,
PRIMARY KEY (`Id`)
) TYPE=MyISAM;


Вставляем данные

INSERT INTO `test` (`Id`,`Numbers`) VALUES (1,1);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (2,4);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (3,6);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (4,12);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (5,19);
INSERT INTO `test` (`Id`,`Numbers`) VALUES (6,318);


Выполняем запрос

SELECT * FROM `test` WHERE `Numbers` LIKE '%1%' AND `Numbers` != 12


Результат выполнения
Код:
+----+---------+
| Id | Numbers |
+----+---------+
|  1 |       1 |
|  3 |       19|
|  6 |      318|
+----+---------+
3 rows in set (0.00 sec)
Мдааа... Помог, помог.
 

MajestiC

Пых
Для строк типа ",3,5,10,3,1,10,3,"

[sql]SELECT * from `test` WHERE `Numbers` LIKE '%,1,%'[/sql]

Но тогда для нужно в начале и в конце добавить по запятой
 

sky19

Новичок
Автор оригинала: MajestiC
Для строк типа ",3,5,10,3,1,10,3,"

[sql]SELECT * from `test` WHERE `Numbers` LIKE '%,1,%'[/sql]

Но тогда для нужно в начале и в конце добавить по запятой
Да такой вариант подходит, даже без запятой в конце, просто искать %,1 %,19 ...

-~{}~ 31.03.06 14:27:

Автор оригинала: asm
FIND_IN_SET()
Скажите, а это функция сумеет разобрать строчку по запятым для дальнейшего сравнивания?
 

ixti

Новичок
sky19
а если 1 будет в самом начале?
Т.е. у тебя будет запись типа "1,19,23" в этом случае поиск "%,1" тебе вряд ли что-либо даст

FIND_IN_SET'ом, который советовал asm можешь сделать такой запрос:
Код:
SELECT * FROM `test` WHERE FIND_IN_SET('1', `Numbers`) >=1;
Но вот "разобрать строчку по запятым для дальнейшего сравнивания" она не сможет.
Она возвращает номер позиции найденной строки в списке...
Т.е. mysql> FIND_IN_SET('1', '200,12,23,123,1'); вернет 5, в случае если подстроки не содержится вернет 0.
 

Never

Новичок
дурной вариант, на случай, если переделывать то что есть будет лень:

where a like '1,%' or a like '%,1,%' or like '%,1'
 

ixti

Новичок
Never
имхо FIND_IN_SET все же больше подходит, так как выполняет по сути тоже самое, но красивее, можно даже написать так:
Код:
SELECT * FROM `test`
  WHERE FIND_IN_SET('1', `Numbers`) <> 0
  AND FIND_IN_SET('12', `Numbers`) = 0;
 

sky19

Новичок
Автор оригинала: Never
дурной вариант, на случай, если переделывать то что есть будет лень:

where a like '1,%' or a like '%,1,%' or like '%,1'
Вот это хороший вариант.
Вроде все подходит, получается такой запрос:

WHERE f_main.offline != 0
AND f_main.f_zanr like '$sort1,%' or f_main.f_zanr like '%,$sort1,%' or f_main.f_zanr like '%,$sort1'

-~{}~ 17.05.06 20:07:

Теперь странность началась вот какая:

если в f_zanr = "10,11,12,13";
а ищу я 12

он выдает найденную карточку но 4 раза подряд...
 

zerkms

TDD infected
Команда форума
[мысля]
именно потому, что к единственно правильному ответу в данном треде (естественно номер 2) никто даже и не подумал прислушаться, в этой же теме постоянно будет нытьё на тему "а у меня запрос работает по 20 секунд" и "помогите сделать хитрый запрос - есть такая вот кривая структура, а нужно сделать такой запрос".
хотя умные люди уже давно выработали методики хранения и работы с данными, однако постоянно находятся велосипедисты которые делают так, как приходит в течение первых 5 минут обдумывания задачи, а потом - "если переделывать то что есть будет лень:"
[/мысля]

спасибо за внимание
 
Сверху