2010-05-20 3 views
3

У меня есть 3 таблицы, 'и' 'D' 'S'PHP SQL, SELECT соответствующие данные из трех таблиц одновременно?

'и' имеет

  • Идентификатор_пользователя
  • DIVID

'd' имеет

  • деление
  • divname

's' имеет

  • SNAME
  • primaryuserid
  • secondaryuserid

Теперь то, что я хотел бы сделать, это отобразить таблицу с строками следующего формата:

  • идентификатор пользователя, divname, SNAME

Плюс выяснить способ, чтобы расшифровать, является ли первичным или вторичным для этой таблицы SNAME идентификатор пользователя.

Я могу показать userid и divname, используя левое соединение, но я не знаю, как бы добавить третью таблицу? Чтобы сделать это сложнее, для каждого пользователя может быть более одного вызова, до ~ 20. Есть ли способ отображать 0-20 имен в зависимости от идентификатора пользователя, разделенных запятыми?

То, что у меня есть в настоящее время, это просто и u и d таблицы, соответствующие друг другу.

SELECT 
    e.userid, 
    e.divid, 
    d.divname 
FROM 
    e 
LEFT JOIN d ON (e.divid = d.id) 
ORDER BY e.userid 
+0

Немного больше объяснений того, как ваши таблицы относятся друг к другу, помогут. Например, вы могли бы дать нам левое соединение, которое вы используете? – Chris

+0

ВЫБОР e.userid, d.divname ОТ е LEFT JOIN D ВКЛ (e.divid = d.divid) ORDER BY e.userid К сожалению по поводу отсутствия редактирования, могу» t отформатировать его в поле комментариев – Flarex

ответ

2

Здесь вы ищете пару разных вещей. Прежде всего, «способ отображать 0-20 имен в зависимости от идентификатора пользователя, разделенных запятыми», может быть выполнен с помощью функции GROUP_CONCAT() MySQL, поэтому ваш запрос будет выглядеть так (без различия между первичными и вторичными):

SELECT u.userid, 
    d.divname, 
    GROUP_CONCAT(s.sname SEPARATOR ', ') AS "snames" 
FROM u 
    LEFT JOIN d ON d.divid = u.divid 
    LEFT JOIN s ON (s.primaryuserid = u.userid OR s.secondaryuserid = u.userid); 

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

SELECT u.userid, 
    d.divname, 
    GROUP_CONCAT(s.sname SEPARATOR ', ') AS "snames", 
    'Primary' AS "category" 
FROM u 
    LEFT JOIN d ON d.divid = u.divid 
    LEFT JOIN s ON s.primaryuserid = u.userid 
UNION ALL 
SELECT u.userid, 
    d.divname, 
    GROUP_CONCAT(s.sname SEPARATOR ', ') AS "snames", 
    'Secondary' AS "category" 
FROM u 
    LEFT JOIN d ON d.divid = u.divid 
    LEFT JOIN s ON s.secondaryuserid = u.userid 

Это даст вам две строки (одна первичных, один Secondary) для каждого идентификатора пользователя с разделенными запятыми списков snames.

1

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

select 
    u.userid 
, d.divname 
, coalesce(s1.sname, s2.sname) 
, case when s1.sname is not null then 'Primary' 
     when s2.sname is not null then 'Secondary' 
     else 'None' end 
from u 
join d on d.divid = u.divid 
left join s s1 on s1.primaryuserid = u.userid 
left join s s2 on s2.secondaryuserid = u.userid 

Отображение до 20 имен пользователей, разделенных запятой является лучше всего сделать на стороне клиента, в PHP. Это можно сделать в базе данных, но метод зависит от вашей СУБД. Для MySQL ограничение подзапроса на 20 строк сложно, но создание разделенных запятыми списков легко. Например:

select 
    group_concat(coalesce(s1.sname,s2.sname) separator ',') 
, ... 
from u 
... 
group by u.userid 
+0

У меня возникают проблемы с вызовом isnull в 4-й строке. MySQL дает мне ошибки и ищет его онлайн, похоже, что он может принимать только один параметр. Я думаю, что, возможно, я недостаточно четко сформулировал свой вопрос в отношении 's' и sname. sname никогда не будет пустым, однако у него может не быть привязанного к нему идентификатора пользователя. Он может иметь до 2, первичный и вторичный идентификатор пользователя. – Flarex

+0

@ user346325: RIght, 'isnull' должен быть' coalesce' для MySQL. Он проверяет значение null, потому что если левое соединение с 's1' ничего не найдет, оно установит все поля' s1' в значение null – Andomar

+0

Я еще не пробовал group_concat, но он кажется достаточно простым. Спасибо за совместный подход. Это значительно упрощает код по сравнению с тем, что я пытался сделать! – Flarex

0

Создайте внутренний вход и поместите его в поле зрения. Затем мы можем просто выбрать выделение в представлении.

Смежные вопросы