Как объединить строки из двух таблиц SQL без дублирования строк? - PullRequest
2 голосов
/ 23 июня 2010

Я полагаю, что этот запрос является немного базовым, и я должен знать больше о SQL, но пока еще мало что сделал с объединениями, что, я думаю, является решением здесь.

То, что у меня есть, это таблица людей и таблица рабочих мест, которые они выполняют. У человека может быть несколько рабочих мест, и я хочу иметь один набор результатов со строкой на человека, содержащей его данные и рабочие должности.

Ниже приведены два примера таблиц (people и job_roles), чтобы вы могли легче понять вопрос.

Люди

<strong> id |  name  |    email_address   |  phone_number</strong>
 1  |  paul  |  paul@example.com  |  123456
 2  |   bob  |  bob@example.com   |  567891
 3  |  bart  |  bart@example.com  |  987561

job_roles

<strong> id  |  person_id  |     job_title   | department</strong>
  1  |      1      |     secretary   |    hr
  2  |      1      |     assistant   |   media
  3  |      2      |      manager    |    IT
  4  |      3      |  finance clerk  |  finance
  4  |      3      |      manager    |    IT

чтобы я мог выводить каждого человека и его роли вот так

Name: paul
Email Address: paul@example.com
Phone: 123456
Job Roles: 
Secretary for HR department
Assistant for media department
_______
Name: bob
Email address: bob@example.com
Phone: 567891
Job roles:
Manager for IT department

Итак, как мне получить информацию о каждом человеке (из таблицы людей) вместе с данными о работе (из таблицы job_roles) для вывода, как в примере выше. Я предполагаю, что это был бы какой-то способ объединения их заданий и соответствующих отделов в столбец заданий, который можно разделить для вывода, но, возможно, есть лучший способ и как будет выглядеть sql?

Спасибо

Пол

PS это будет база данных mySQL, если это будет иметь значение

Ответы [ 4 ]

3 голосов
/ 24 июня 2010

Это выглядит как прямое соединение:

SELECT p.*, j.*
  FROM People AS p INNER JOIN Roles AS r ON p.id = r.person_id
 ORDER BY p.name;

Остальная часть работы - форматирование;это лучше всего сделать с помощью пакета отчетов.


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

id | Name | email_address    | phone_number | job_role  | department
 1 | paul | paul@example.com | 123456       | secretary | HR
 1 | paul | paul@example.com | 123456       | assistant | media
 2 | bob  | bob@example.com  | 567891       | manager   | IT

Я бы хотел, чтобы в идеале был один ряд на человека со всеми его рабочими ролями, если это возможно?

Это зависит от вашей СУБД, но большинство доступных не поддерживают RVA - атрибуты со значениями отношений.То, что вам нужно, это иметь роль задания и часть отдела в виде таблицы, связанной с пользователем:

+----+------+------------------+--------------+------------------------+
| id | Name | email_address    | phone_number |   dept_role            |
+----+------+------------------+--------------+------------------------+
|    |      |                  |              | +--------------------+ |
|    |      |                  |              | | job_role   | dept  | |
|  1 | paul | paul@example.com | 123456       | | secretary  | HR    | |
|    |      |                  |              | | assistant  | media | |
|    |      |                  |              | +--------------------+ |
+----+------+------------------+--------------+------------------------+
|    |      |                  |              | +--------------------+ |
|    |      |                  |              | | job_role   | dept  | |
|  2 | bob  | bob@example.com  | 567891       | | manager    | IT    | |
|    |      |                  |              | +--------------------+ |
+----+------+------------------+--------------+------------------------+

Это точно представляет требуемую информацию, но обычно это не вариант.

Итак, что будет дальше, зависит от вашего инструмента генерации отчетов.Используя тот, с которым я наиболее знаком (Informix ACE, часть Informix SQL, доступная от IBM для использования с СУБД Informix), вы просто убедитесь, что данные отсортированы, а затем напечатаете имя, адрес электронной почты и номер телефона.в разделе отчета «ДО ГРУППЫ ИД» и в разделе «НА КАЖДОЙ СТРОКЕ» вы будете обрабатывать (распечатывать) только информацию о роли и отделе.

Часто хорошей идеей является разделениеформатирование отчета по операциям поиска данных;это пример того, где это необходимо, если ваша СУБД не имеет необычных функций, помогающих форматировать выбранные данные.


О, дорогой, это звучит очень сложно, и я не смог бы легко с этим работатьбазу данных mySQL на странице PHP?

Материал RVA - вы правы, это не для MySQL и PHP.

С другой стороны, существуют миллионы отчетов(имеется в виду результаты запросов, отформатированных для представления пользователю), которые примерно это делают.Технический термин для них: « Отчет об отключении управления », но основная идея не сложна.

Вы ведете запись числа «id», которое вы обработали в последний раз - вы можете инициализироватьчто до -1 или 0. Когда текущая запись имеет номер идентификатора, отличный от предыдущего, тогда у вас есть новый пользователь, и вам нужно запустить новый набор строк вывода для нового пользователя и напечатать имя, адрес электронной почты иномер телефона (и изменить последний обработанный номер идентификатора).Когда текущая запись имеет тот же идентификационный номер, все, что вам нужно сделать, это обработать информацию о роли и отделе работы (не имя, адрес электронной почты и номер телефона).«Перерыв» происходит при изменении номера идентификатора.С одним уровнем нарушения контроля это не сложно;если у вас 4 или 5 уровней, вам нужно проделать больше работы, и поэтому есть пакеты отчетов, которые справляются с этим.

Так что это не сложно - просто нужно немного позаботиться.

2 голосов
/ 24 июня 2010

RE:

Я надеялся, что SQL сможет что-то сделать умный и объединить ряды хорошо, поэтому у меня была по существу работа колонка с указанными в ней лицами.

Вы можете довольно близко подойти к

SELECT  p.id, p.name, p.email_address, p.phone_number,
group_concat(concat(job_title, ' for ', department, ' department')  SEPARATOR '\n') AS JobRoles
FROM People AS p 
    INNER JOIN job_roles AS r ON p.id = r.person_id
GROUP BY p.id, p.name, p.email_address, p.phone_number
 ORDER BY p.name;
0 голосов
/ 24 июня 2010

Одним из способов может быть левое внешнее объединение таблиц, а затем загрузка их в массив с помощью

$people_array =array(); 
while($row1=mysql_fetch_assoc($extract1)){ 
$people_array[] = $row1;  
} 

, а затем выполнить цикл с помощью

 for ($x=0;$x<=sizeof($people_array;) 
    {  
echo $people_array[$x][id]; 
echo $people_array[$x][name]; 

for($y=0;$y<=$number_of_roles;$y++) 
{ 
 echo $people_array[$x][email_address]; 
 echo $people_array[$x][phone_number]; 
    $x++; 
} 
     } 

Возможно, вам придется немного поиграть с запросом и циклами, но в целом он должен выполнять то, что вы хотите. Чтобы он работал так, как указано выше, каждый человек должен иметь одинаковое количество ролей, но вы можете заполнить в заготовках на вашем столе

0 голосов
/ 24 июня 2010

Выполнение этого так, как вам нужно, будет означать, что массивы результирующих наборов могут иметь бесконечные столбцы, что будет очень грязно. например, вы можете оставить присоединиться к таблице заданий 10 раз и получить задания job1, job2, .. job10.

Я бы сделал одно соединение, а затем использовал бы PHP, чтобы проверить, совпадает ли идентификатор имени от 1 строки до следующей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...