2010-02-19 7 views
3

У нас есть простая база данных. В таблице пользователя содержатся пользователи. В таблице «Учетные записи» есть несколько учетных записей для каждого пользователя. В таблице «Темы» содержатся несколько тем для каждой учетной записи.Как эффективно выполнять sql-запрос дочерних записей из нескольких таблиц?

Итак, у пользователя будет несколько учетных записей, и каждая учетная запись будет иметь несколько тем. Итак, если у меня есть пользователь с id = 1, как я могу эффективно запросить все 3 таблицы, чтобы получить все учетные записи и темы для этого пользователя?

В настоящее время я использую петли foreach, которые запускают много запросов sql. Есть ли способ запустить один SQL-запрос, чтобы получить то, что я хочу?

Вот код, который я сейчас использую (что CodeIgniter код):

$data=array(); 
$accounts=$this->db->get_where('accounts',array('user_id'=>1)); 
foreach ($accounts->result() as $account) { 
    $tmp=array(); 
    $topics=$this->db->get_where('topics',array('account_id'=>$account->id)); 
    foreach ($topics->result() as $topic) { 
     $this->db->order_by($order_by); 
     $terms=$this->db->get_where('terms',array('topic_id'=>$topic->id)); 
     array_push($tmp,array('topic'=>$topic, 'terms'=>$terms->result())); 
    } 
    array_push($data,array('account'=>$account, 'topics'=>$tmp)); 
} 
return $data; 
+0

Вы ищете для SQL присоединиться? Или более элегантный PHP-синтаксис с использованием codeignitor? –

+0

Должно ли это сделать на стороне SQL, проблема с данными, а не проблема с пользовательским интерфейсом. – JonH

+0

Что делать, если у одной из учетных записей еще нет тем? Вы все еще не хотите получать эту учетную запись? То же самое касается терминов. Что, если в теме нет каких-либо условий? Вы хотите восстановить тему? Возможно, эти ситуации невозможны, но если они есть, они являются важными деталями. – goat

ответ

3

Просто один ко многим другим один ко многим.

User-> Многие Accounts

счет-> Многие темы

Think вашей таблицы пользователей, что одна строка является уникальным (содержит один пользователь сказал Джон Доу). Подумайте о вашей таблице счетов, ссылающейся на своего рода пользователя (то есть на нескольких учетных записях может быть один и тот же пользователь, кроме того, учетные записи Acme 1 и Acme 2 оба относятся к пользователю Jon Doe). Наконец, подумайте о своей таблице тем, содержащей ссылку на учетную запись. У каждой темы есть идентификатор учетной записи. Таким образом, у учетных записей есть много связанных с ними тем.

SELECT 
    u.UserID, 
    a.Account 
    t.Topic 
FROM 
    Users u 
INNER JOIN 
    Accounts a 
ON u.UserID = a.UserID 
INNER JOIN 
    Topics t 
ON t.AccountID = a.AccountID 

Если вы хотите, чтобы сузить в на одного пользователя просто добавить предложение WHERE:

SELECT 
    u.UserID, 
    a.Account 
    t.Topic 
FROM 
    Users u 
INNER JOIN 
    Accounts a 
ON u.UserID = a.UserID 
INNER JOIN 
    Topics t 
ON t.AccountID = a.AccountID 
WHERE u.UserID=1 
+0

Он хорошо работает, хотя кажется, что «a.Account» и «t.Topic» являются определенными полями в таблицах «Аккаунты» и «Темы». Я могу получить определенные поля, используя «SELECT u.id as user_id, a.id as account_id, t.id как topic_id ...», но есть ли способ выбрать всю запись, а не указывать каждое поле? – bperdue

+0

Если вы хотите, чтобы в каждой записи вы могли получить дикую карту, ВЫ ВЫБРАТЬ u. *, T. * ... и т. Д. Хотя я советую не использовать дикие карты ... вы всегда должны перечислять каждое поле – JonH

+0

Nevermind, я получил его от dkantowitz ниже: «SELECT u. *, a. *, t. * ..." – bperdue

0
SELECT top.`topic_id` [etc] 
FROM `accounts` acc 
JOIN `topics` top ON (top.`account_id` = acc.`id`) 
WHERE acc.`member_id` = 1 

Является основной запрос, не уверен, что CI.

, если вам нужна другая информация от члена ид, то:

SELECT usr.`id`, acc.`account_id`, top.`topic_id` [etc] 
FROM `users` usr 
JOIN `accounts` acc ON (acc.`member_id` = usr.`id`) 
JOIN `topics` top ON (top.`account_id` = acc.`id`) 
WHERE usr.`id` = 1 
Смежные вопросы