Фильтры (Выборка по категориям)

@lexander

Новичок
Фильтры (Выборка по категориям)

На текущий момент есть таблица проектов
id, name, cat1, cat2, cat3 ... cat8, cat9
Т.е. есть 9 категорий в которых может находится конкретный проект.
Смысл заключается в том, что пользователь, просматривая каталог, может делать выборку

проектов из различных категорий и исключать из выборки проекты из других категорий.

Делается это посредством
[sql]
SELCT id From projects WHERE
(
cat1 IN (1,2,3)
OR cat2 IN (1,2,3)
OR cat3 IN (1,2,3)
- - - - - - - - -
OR cat8 IN (1,2,3)
OR cat9 IN (1,2,3)
)
AND
(
cat1 NOT IN (4,5,6)
AND cat2 NOT IN (4,5,6)
AND cat3 NOT IN (4,5,6)
- - - - - - - - -
AND cat8 NOT IN (4,5,6)
AND cat9 NOT IN (4,5,6)
)[/sql]
Где 1,2,3 - необходимые категории, а
4,5,6 - исключаемые.

Например:
Код:
id cat1 cat2 cat3 cat4 cat5 cat6 cat7 cat8 cat9
1  1    7    9    0    0    0    0    0    0
2  2    5    10   0    0    0    0    0    0
3  1    8    0    0    0    0    0    0    0
Запрос вернёт
Код:
id
1
3
Можно ли оптимизировать такую выборку?
Пробовал перейти на таблицы ссылок
Код:
project    cat
1          1
1          7
1          9 
2          2
2          5
2          10
3          1
3          8
Как добиться результата
Будет ли это быстрее?
При 1,2,3 - необходимые категории, а
4,5,6 - исключаемые.

Должен вернуть
Код:
project
1
3
 

Сергей123

Новичок
Поменять структуру.
Таблица проектов: idпроекта, имяпроекта.
Таблица категорий проектов: idкатегории, имякатегории.
Таблица связей проектов и категорий: idпроекта, idкатегории. В этой третьей таблице может быть 0, 1, 2, сколько угодно записей с конкретным idпроекта. Например, в твоём примере проект 1 - в трёх категориях - 1, 7 и 9. Значит, в этой третьей таблице у тебя будут записи
1 1
1 7
1 9

Так твои выборки намного упростятся.
 

@lexander

Новичок
>Таблица проектов: idпроекта, имяпроекта.
>Таблица категорий проектов: idкатегории, имякатегории.
>Таблица связей проектов и категорий: idпроекта, idкатегории.

А вы первый пост читали?
Эта структура и так уже есть :)
Вопрос в том, как выбрать из таблицы связей проектов так, чтобы получить такой же результат, как из первоначальной структуры или оптимизировать последнюю.
 

chira

Новичок
@lexander

для варианта с таблицей связей
Код:
SELECT id FROM projects p
  INNER JOIN pr_cat pc1 ON p.id = pc1.pr_id AND pc1.cat_id IN ( 1, 2, 3 )
  LEFT JOIN pr_cat pc0 ON p.id = pc0.pr_id AND pc0.cat_id IN ( 4, 5, 6 )
WHERE pc0.pr_id IS NULL
 

@lexander

Новичок
Огромное спасибо.
Всё заработало :))
Сейчас вот только думаю:
Использовать DISTINCT или переложить это на плечи PHP...

-~{}~ 11.02.07 13:42:

Подскажите, пожалуйста, как можно выбрать id проектов и ВСЕ их категории, модифицировав вышеприведенный запрос?
 
Сверху