Я пытаюсь создать способ поиска в базе данных клиентов, где некоторые фрагменты данных, такие как номера телефонов и электронные письма, имеют отношение один ко многим.У меня есть таблица с идентификатором клиента (уникальный, автономный номер), именем и фамилией.У меня есть вторая таблица, содержащая номер телефона и идентификатор клиента, с которым связан этот номер телефона.У меня есть третья таблица, содержащая адрес электронной почты и идентификатор клиента, с которым связан этот адрес электронной почты.
Вот запрос, встроенный в PHP:
$query = "SELECT *
FROM customers
LEFT OUTER JOIN phone_numbers ON customers.customer_id = phone_numbers.associated_customer
LEFT OUTER JOIN email_addresses ON customers.customer_id = email_addresses.associated_customer
WHERE first_name LIKE '%" . $_GET["fname"] . "%'
AND last_name LIKE '%" . $_GET["lname"] . "%'
AND phone_number LIKE '%" . $_GET["phone"] . "%'
AND email_address LIKE '%" . $_GET["email"] . "%'";
При этом клиентЯ искал только подходит, если у них есть номер телефона и адрес электронной почты.Я также получаю дубликаты результатов из первой таблицы, если у клиента есть несколько телефонных номеров или электронных писем, поэтому, если у клиента есть 2 телефонных номера и 2 электронных письма, я получу 4 результата назад.
Правильно ли я структурирую свои таблицыдля достижения этого отношения один ко многим?
РЕДАКТИРОВАТЬ: Пример данных для уточнения.
Таблица 1:
╔════════════════════════════════════════╗
║ customers ║
╠═════════════╦════════════╦═════════════╣
║ customer_id ║ first_name ║ last_name ║
╠═════════════╬════════════╬═════════════╣
║ 1 ║ John ║ Doe ║
║ 2 ║ John ║ Wick ║
║ 3 ║ John ║ Cena ║
║ 4 ║ John ║ Krasinski ║
║ 5 ║ Jane ║ Doe ║
║ 6 ║ Freddie ║ Mercury ║
╚═════════════╩════════════╩═════════════╝
Таблица 2:
╔══════════════════════════════════════════════════╗
║ phone numbers ║
╠════════════════╦═══════════════╦═════════════════╣
║ phone_number ║ associated_id ║ primary_contact ║
╠════════════════╬═══════════════╬═════════════════╣
║ 5555555555 ║ 2 ║ 0 ║
║ 6692216251 ║ 2 ║ 1 ║
║ 2025550174 ║ 3 ║ 1 ║
╚════════════════╩═══════════════╩═════════════════╝
таблица 3:
╔═══════════════════════════════════════════════════╗
║ email_addresses ║
╠═════════════════╦═══════════════╦═════════════════╣
║ email_address ║ associated_id ║ primary_contact ║
╠═════════════════╬═══════════════╬═════════════════╣
║ jdoe@aol.com ║ 1 ║ 1 ║
║ jwick@email.com ║ 2 ║ 1 ║
║ jwick@aol.com ║ 2 ║ 0 ║
╚═════════════════╩═══════════════╩═════════════════╝
поисковый запрос:
first name: "John"
last name: ""
phone number: ""
email address: ""
Ожидается, что он вернет все совпадения для «Джона» в поле первого имени и тольковключите основные методы контакта:
╔═════════════╦════════════╦═════════════╦══════════════╦═════════════════╗
║ customer_id ║ first_name ║ last_name ║ phone_number ║ email_address ║
╠═════════════╬════════════╬═════════════╬══════════════╬═════════════════╣
║ 1 ║ John ║ Doe ║ ║ jdoe@aol.com ║
║ 2 ║ John ║ Wick ║ 6692216251 ║ jwick@email.com ║
║ 3 ║ John ║ Cena ║ 2025550174 ║ ║
║ 4 ║ John ║ Krasinski ║ ║ ║
╚═════════════╩════════════╩═════════════╩══════════════╩═════════════════╝
Фактический результат состоит в том, что все результаты, которые не имеют ассоциированного номера телефона и адреса электронной почты, исключаются, и дубликат включается для каждого номера телефона и каждого адреса электронной почты.:
╔═════════════╦════════════╦═════════════╦══════════════╦═════════════════╗
║ customer_id ║ first_name ║ last_name ║ phone_number ║ email_address ║
╠═════════════╬════════════╬═════════════╬══════════════╬═════════════════╣
║ 2 ║ John ║ Wick ║ 5555555555 ║ jwick@email.com ║
║ 2 ║ John ║ Wick ║ 6692216251 ║ jwick@email.com ║
║ 2 ║ John ║ Wick ║ 5555555555 ║ jwick@aol.com ║
║ 2 ║ John ║ Wick ║ 6692216251 ║ jwick@aol.com ║
╚═════════════╩════════════╩═════════════╩══════════════╩═════════════════╝
Однако предположим, что мой поисковый запрос выглядит следующим образом:
first name: "John"
last name: ""
phone number: "5555555555"
email address: ""
Ожидаемый результат будет:
╔═════════════╦════════════╦═════════════╦══════════════╦═════════════════╗
║ customer_id ║ first_name ║ last_name ║ phone_number ║ email_address ║
╠═════════════╬════════════╬═════════════╬══════════════╬═════════════════╣
║ 2 ║ John ║ Wick ║ 5555555555 ║ jwick@email.com ║
╚═════════════╩════════════╩═════════════╩══════════════╩═════════════════╝
Язнать о атаках SQL инъекций.У меня будут меры по их предотвращению, но это будет внутренняя система, так что меня это не сильно волнует.