Как мне написать этот запрос? - PullRequest
2 голосов
/ 29 сентября 2010

Я хотел бы написать следующее как оператор MySQL SELECT, чтобы сократить количество запросов, необходимых для получения информации, но я не уверен, как ее написать.

У меня есть дватаблицы - теги и books_tags (таблица соединений отношения «многие ко многим»).Окончательный вывод, который мне нужен, будет печататься следующим образом:

<label for="formFiltertag1"><input type="checkbox" name="tag[]" value="1" id="formFiltertag1" class="rank90" /> PHP (15)<br /></label>

Где текст - это имя тега (tags.name), а число в скобках - это счетчик того, как часто идентификатор тега появляется всоединительная таблица (COUNT (books_tags.tag_id)).Идентификатор и значение ввода будут динамическими в зависимости от поля tags.id.

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

Вот пример, который я сейчас написал (используя шаблон ActiveRecord CodeIgniter) ...

Модель:

function get_form_tags() {
    $query = $this->db->get('tags');
    $result = $query->result_array();
    $tags = array();
    foreach ($result as $row) {
        $this->db->select('tag_id')->from('books_tags')->where('tag_id', $row['id']);
        $subResult = $this->db->count_all_results();
        $tags[] = array('id' => $row['id'], 'tag' => $row['tag'], 'count' => $subResult);
    }
    return $tags;
}

Контроллер:

function index() {
    $this->load->model('browse_model', 'browse');
    $tags = $this->browse->get_form_tags();

    $data['content'] = 'browse/browse';
    $data['tags'] = $tags;
    $this->load->view('global/template', $data);
}

Представление (сокращенно):

<?php foreach ($tags as $tag) : ?>
<label for="formFiltertag<?php echo $tag['id'] ?>"><input type="checkbox" name="tag[]" value="<?php echo $tag['id'] ?>" id="formFiltertag<?php echo $tag['id'] ?>" class="rank<?php echo $tag['count'] ?>" /> <?php echo $tag['tag'] . ' (' . $tag['count'] . ')' ?><br /></label>
<?php endforeach; ?>

Это работает, но, как я уже сказал, это создаст гораздо больше запросов, чем необходимо для выполнения работы.Конечно, есть лучший способ.Пенни за твои мысли?

Большое спасибо, Маркус

Ответы [ 2 ]

2 голосов
/ 29 сентября 2010
select t, coalesce(btc.Count, 0) as Count
from tags t
left outer join (
    select tagid, count(*) as Count
    from books_tags 
    group by tagid
) btc on t.tagid = btc.tagid
1 голос
/ 29 сентября 2010

$result возвращает массив массивов, где array_combine() ожидает массив строк.

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