(Использование MySQL и PHP)
У меня есть форма поиска, которая позволит моим пользователям вводить строку и искать эту строку по конкретным критериям.
Моя проблема заключается в том, что пользователь должен иметь возможность искать информацию, которая "распространяется" по нескольким таблицам. Например:
-Table "users" содержит имя, имя, роль, имя пользователя (PK)
-Table "помощник-резидент" содержит имя пользователя (FK для пользователей), здание, комнату, область
-Table "координатор области" содержит имя пользователя (FK для пользователей), office_bldg, office_num
И я разрешаю своим пользователям искать по имени, фамилии, зданию, региону, офису #, поэтому мне нужно будет показывать результаты, которые охватывают несколько таблиц (т.е. сопоставление записей от "пользователей" и "помощник резидента", )
Я экспериментировал с Joins and Unions, но не получил ничего полезного. Я ищу самую "универсальную" инструкцию SQL для обработки любого поиска, если это возможно.
Прямо сейчас, единственный способ, которым я могу думать о выполнении этих поисков, - это много обработки в PHP, например, чтобы найти Имя, иметь запрос, который возвращает имя пользователя, роль от "пользователей", а затем есть куча утверждений if, говорящих: "Если роль такова, тогда выполните поиск в этой таблице, где username равно этому..."
Есть ли лучший способ сделать это?
Винко -
Я действительно не получаю ошибку, запрос (с несколькими объединениями) просто возвращает 0 строк.
Вот пример запроса, который я использую:
select u.fname, u.lname, u.role, u.username, r.building, r.room, r.region,
a.office, a.office_num
from
users u
join `ra_ca` r on (u.username = r.username)
join `area_coord` a on (u.username = a.username)
where
u.username = 'behrk2' and r.region = '4'
И вот мои структуры таблицы:
CREATE TABLE `users` (
`fname` varchar(50) NOT NULL,
`lname` varchar(50) NOT NULL,
`role` varchar(75) NOT NULL,
`extension` int(4) default '6226',
`username` varchar(25) NOT NULL,
`password` varchar(75) NOT NULL,
`new_pass` varchar(5) default NULL,
PRIMARY KEY (`username`),
KEY `role` (`role`),
CONSTRAINT `users_ibfk_1` FOREIGN KEY (`role`) REFERENCES `role` (`role`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `ra_ca` (
`username` varchar(25) NOT NULL,
`region` tinyint(4) NOT NULL,
`building` varchar(75) NOT NULL,
`room` varchar(10) NOT NULL,
PRIMARY KEY (`username`),
KEY `region` (`region`),
KEY `building` (`building`),
CONSTRAINT `ra_ca_ibfk_9` FOREIGN KEY (`building`) REFERENCES `building` (`building`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `ra_ca_ibfk_7` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `ra_ca_ibfk_8` FOREIGN KEY (`region`) REFERENCES `region` (`region`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
CREATE TABLE `area_coord` (
`username` varchar(25) NOT NULL,
`region` tinyint(4) NOT NULL,
`building` varchar(75) NOT NULL,
`room` varchar(10) NOT NULL,
`office` varchar(75) NOT NULL,
`office_num` varchar(10) NOT NULL,
PRIMARY KEY (`username`),
KEY `region` (`region`),
KEY `building` (`building`),
CONSTRAINT `area_coord_ibfk_9` FOREIGN KEY (`building`) REFERENCES `building` (`building`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `area_coord_ibfk_7` FOREIGN KEY (`username`) REFERENCES `users` (`username`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `area_coord_ibfk_8` FOREIGN KEY (`region`) REFERENCES `region` (`region`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
И у меня есть значения в БД...
С чем-то вроде следующего вам нужно будет только создать код предложения where. Это последняя строка запроса.
select u.fname, u.lname, u.role, u.username, r.building, r.room, r.region,
a.office_bldg, a.office_num
from
users u
join `resident assistant` r on (u.username = r.username)
join `area coordinator` a on (u.username = a.username)
where
u.username = 'foo' and r.region = 'China'
EDIT:
Мне кажется, что вы хотите получить все результаты независимо от того, есть ли значения во всех связанных таблицах. Поэтому попробуйте левые соединения вместо внутренних соединений. Попробуйте прочитать SQL, чтобы знать, ЧТО эти запросы выполняют.
select u.fname, u.lname, u.role, u.username, r.building, r.room, r.region,
a.office_bldg, a.office_num
from
users u
left join `resident assistant` r on (u.username = r.username)
left join `area coordinator` a on (u.username = a.username)
where
u.username = 'foo' and r.region = 'China'