Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложное хранение доп. полей. Гуру помогите - горит проект. / 5 сообщений из 5, страница 1 из 1
11.03.2014, 01:20:43
    #38582633
Mlexion
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложное хранение доп. полей. Гуру помогите - горит проект.
Всем привет. Заранее благодарен всем кто откликнется.

Суть проекта - доска объявлений, аналог авито, только для недвижимости.
Гуглил готовые варианты - подходящих кандидатов не нашел. Решил писать велосипед. Заглохло все на доп. параметрах. Есть 3 таблицы(их больше, но играют роль сейчас только 3).

ci_board - Хранение основной инфы: заголовок, ид, ид пользователя который добавил и т.п.

ci_board_tv -Хранение значений доп параметров. ид доп параметра, ид основной записи(ci_board) значение доп параметра(int)

ci_board_tv_types - типы до параметров(int,text,number и тп)

Структура таблиц

ci_board
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
CREATE TABLE `ci_board` (
	`id` MEDIUMINT(9) UNSIGNED NOT NULL AUTO_INCREMENT,
	`city` MEDIUMINT(9) UNSIGNED NOT NULL,
	`district` SMALLINT(6) NOT NULL COMMENT 'Район',
	`category` MEDIUMINT(9) UNSIGNED NOT NULL,
	`user_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
	`title` VARCHAR(255) NOT NULL,
	`text` TEXT NOT NULL,
	`autor` VARCHAR(40) NOT NULL,
	`price` INT(11) NOT NULL,
	`pos_x` DECIMAL(10,6) NOT NULL DEFAULT '54.782535',
	`pos_y` DECIMAL(10,6) NOT NULL DEFAULT '32.044149',
	`video` VARCHAR(225) NULL DEFAULT '32.04414946',
	`addres` VARCHAR(225) NULL DEFAULT '32.04414946',
	`date_create` DATETIME NOT NULL,
	`date_update` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
	PRIMARY KEY (`id`),
	INDEX `user_id` (`user_id`),
	INDEX `category` (`category`),
	INDEX `city` (`district`, `city`),
	INDEX `date_create` (`date_create`),
	INDEX `pos` (`pos_x`, `pos_y`),
	FULLTEXT INDEX `title` (`title`, `text`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;
INSERT INTO `ci_board` (`id`, `city`, `district`, `category`, `user_id`, `title`, `text`, `autor`, `price`, `pos_x`, `pos_y`, `video`, `addres`, `date_create`, `date_update`) VALUES
	(1, 1, 1, 1, 1, 'попова 24', 'Описание объявления:\\r\\n', 'mlex', 1499999, 54.773018, 32.088127, NULL, NULL, '2014-03-09 18:07:32', '2014-03-09 18:07:28'),
	(12, 1, 2, 1, 1, 'Название обьявления:', 'Описание объявления:', 'mlex', 199999, 54.768246, 32.096167, NULL, NULL, '2014-03-10 14:29:38', '2014-03-10 14:29:38'),
	(13, 1, 2, 1, 1, 'Название обьявления:', 'Описание объявления:', 'mlex', 199999, 54.768246, 32.096167, NULL, NULL, '2014-03-10 14:30:04', '2014-03-10 14:30:03'),
	(14, 1, 2, 1, 1, 'Название обьявления:', 'Описание объявления:', 'mlex', 199999, 54.768246, 32.096167, NULL, NULL, '2014-03-10 14:31:16', '2014-03-10 14:31:16'),
	(15, 1, 1, 1, 1, 'sdfsdfsf\\\'', 'ssssssssssss \\\'  `', 'mlex', 9, 54.782526, 32.044128, NULL, NULL, '2014-03-10 14:35:47', '2014-03-10 14:35:47');



ci_board_tv
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
CREATE TABLE `ci_board_tv` (
	`tv_id` INT(10) UNSIGNED NOT NULL,
	`board` INT(10) UNSIGNED NOT NULL,
	`value` SMALLINT(6) NULL DEFAULT NULL,
	PRIMARY KEY (`tv_id`, `board`),
	INDEX `value` (`value`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;
INSERT INTO `ci_board_tv` (`tv_id`, `board`, `value`) VALUES
	(1, 0, 2),
	(1, 13, 2),
	(1, 14, 2),
	(1, 15, 1),
	(2, 0, 16),
	(2, 13, 16),
	(2, 14, 16),
	(2, 15, 1),
	(3, 0, 3),
	(3, 13, 3),
	(3, 14, 3),
	(3, 15, 2),
	(4, 0, 3),
	(4, 13, 3),
	(4, 14, 3),
	(4, 15, 1),
	(5, 0, 3),
	(5, 13, 3),
	(5, 14, 3),
	(5, 15, 1),
	(6, 0, 2),
	(6, 13, 2),
	(6, 14, 2),
	(6, 15, 1),
	(7, 0, 1),
	(7, 13, 1),
	(7, 14, 1),
	(7, 15, 1),
	(8, 0, 0),
	(8, 13, 0),
	(8, 14, 0),
	(9, 0, 0),
	(9, 13, 0),
	(9, 14, 0),
	(17, 0, 2),
	(17, 13, 2),
	(17, 14, 2),
	(17, 15, 1);



ci_board_tv_types
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
CREATE TABLE `ci_board_tv_types` (
	`id` INT(11) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(80) NULL DEFAULT NULL,
	`type` ENUM('number','checkbox','select_list','radio','text','textarea','select','yuotube') NOT NULL,
	`value` TINYTEXT NULL,
	PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM;

INSERT INTO `ci_board_tv_types` (`id`, `name`, `type`, `value`) VALUES
	(1, 'Тип жилья', 'radio', '1=Вторичка||2=Новостройка'),
	(2, 'Площадь (м<sup>2</sup>)', 'number', NULL),
	(3, 'Этаж', 'number', NULL),
	(4, 'Тип дома', 'select', '1=кирпичный||2=монолитный||3=панельный'),
	(5, 'Отопление', 'select', '1=автономное||2=индивидуальное||3=центральное'),
	(6, 'Тип комнат', 'radio', '1=изолированные||2= смежные'),
	(7, 'Санузел', 'radio', '1=раздельный||2=совмещённый'),
	(8, 'Возможна ипотека', 'checkbox', '0'),
	(9, 'Без посредников', 'checkbox', '0'),
	(10, 'мебель в комнате', 'checkbox', '0'),
	(11, 'мебель на кухне', 'checkbox', '0'),
	(12, 'холодильник', 'checkbox', '0'),
	(13, 'стиральная машина', 'checkbox', '0'),
	(14, 'можно с детьми', 'checkbox', '0'),
	(15, 'можно с животными', 'checkbox', '0'),
	(16, 'Срок', 'radio', '1=Длительный'),
	(17, 'Количество комнат', 'number', NULL);




Начинаю делать выборку с фильтрацией по доп параметрам
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT * FROM ci_board as b
LEFT JOIN ci_board_tv as tv ON tv.tv_id in (1,2)
WHERE 
tv.board = b.id
AND ((tv.tv_id = 1 AND tv.value = 2)
or (tv.tv_id = 2 AND tv.value = 1))
group by b.id
LIMIT 10



Не получается сделать так что бы можно было корректно выводить из таблицы ci_board значения которые фильтруются по значениям из таблицы ci_board_tv, т.е. " WHERE (ci_board_tv.tv_id = 1 AND ci_board_tv.value = 2) AND (ci_board_tv.tv_id = 2 AND ci_board_tv.value = 3) AND ... ". Не могу понять как фильтровать поля когда к 1й записи в 1й таблице относятся N записей в другой.
Помогите :)
...
Рейтинг: 0 / 0
11.03.2014, 06:07:27
    #38582654
bochkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложное хранение доп. полей. Гуру помогите - горит проект.
либо так
Код: sql
1.
2.
3.
4.
5.
6.
SELECT * FROM ci_board as b
WHERE 
EXISTS(SELECT 1 FROM ci_board_tv as tv 
WHERE tv.board = b.id AND ((tv.tv_id = 1 AND tv.value = 2)
OR (tv.tv_id = 2 AND tv.value = 1)))
LIMIT 10


либо
Код: sql
1.
2.
3.
4.
5.
6.
7.
SELECT DISTINCT b.* FROM ci_board as b
LEFT JOIN ci_board_tv as tv ON tv.tv_id in (1,2)
WHERE 
tv.board = b.id
AND ((tv.tv_id = 1 AND tv.value = 2)
or (tv.tv_id = 2 AND tv.value = 1))
LIMIT 10
...
Рейтинг: 0 / 0
11.03.2014, 06:11:14
    #38582655
transpose
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложное хранение доп. полей. Гуру помогите - горит проект.
я пишу такие джойны так:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT * FROM ci_board as b
LEFT JOIN ci_board_tv as tv 
ON tv.board = b.id
AND 
(
    (tv.tv_id = 1 AND tv.value = 2)
or (tv.tv_id = 2 AND tv.value = 1)
)
group by b.id
LIMIT 10

Mlexion,
А тут
WHERE (ci_board_tv.tv_id = 1 AND ci_board_tv.value = 2) AND (ci_board_tv.tv_id = 2 AND ci_board_tv.value = 3) AND ...
наверное имелось в виду это?
WHERE ( (ci_board_tv.tv_id = 1 AND ci_board_tv.value = 2) OR (ci_board_tv.tv_id = 2 AND ci_board_tv.value = 3) OR ... )
...
Рейтинг: 0 / 0
11.03.2014, 11:28:04
    #38582787
Mlexion
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложное хранение доп. полей. Гуру помогите - горит проект.
bochkov , cgfcb,j - это почти то.

Но если использовать OR в
Код: sql
1.
2.
AND ((tv.tv_id = 1 AND tv.value = 2)
or (tv.tv_id = 2 AND tv.value = 1))


то получается что это не точный поиск по совпадению записей. А если использовать AND то он не находит не одну и это логично. Может как то можно перестроить запрос или разбить его на 2,3 запроса?
...
Рейтинг: 0 / 0
11.03.2014, 14:47:52
    #38582987
bochkov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложное хранение доп. полей. Гуру помогите - горит проект.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
SELECT * FROM ci_board as b
WHERE 
EXISTS(SELECT 1 FROM ci_board_tv as tv 
WHERE tv.board = b.id AND tv.tv_id = 1 AND tv.value = 2)
AND
EXISTS(SELECT 1 FROM ci_board_tv as tv 
WHERE tv.board = b.id AND tv.tv_id = 2 AND tv.value = 1)
LIMIT 10
...
Рейтинг: 0 / 0
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Сложное хранение доп. полей. Гуру помогите - горит проект. / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]