【问题标题】:How should I write this query?我应该如何编写这个查询?
【发布时间】:2010-09-28 20:07:46
【问题描述】:

我想将以下内容编写为 MySQL SELECT 语句,以减少获取信息所需的查询次数,但我不知道如何编写。

我有两个表 - tags 和 books_tags(一个多对多关系连接表)。我想要的最终输出将打印如下:

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

其中文本是标签的名称 (tags.name),括号中的数字是标签 ID 在联结表中出现的频率 (COUNT(books_tags.tag_id))。输入 ID 和值将根据 tags.id 字段动态变化。

我最初以为我只是运行一个从标签表中获取所有信息的查询,然后使用一个 foreach 循环为每个标签运行一个单独的计数查询,但是随着标签数量的增长,这可能会变得笨拙迅速地。

这是我现在编写的示例(使用 CodeIgniter 的 ActiveRecord 模式)...

模型:

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; ?>

这可行,但就像我说过的那样,它会创建比完成工作所需的查询更多的查询。肯定有更好的办法。一分钱你的想法?

非常感谢, 马库斯

【问题讨论】:

    标签: php mysql activerecord codeigniter


    【解决方案1】:
    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
    

    【讨论】:

    • 这适用于一些小的修改。谢谢您的帮助。有谁碰巧知道如何使用 ActiveRecord 方法编写这种复杂的语句?
    【解决方案2】:

    $result 返回一个数组数组,其中array_combine() 需要一个字符串数组。

    【讨论】:

    • 好信息 - 谢谢。我现在重写了上面的代码示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多