【问题标题】:Select active data by order按顺序选择活动数据
【发布时间】:2018-08-21 01:47:19
【问题描述】:

我有两个表postscategories,两个表之间存在one-to-many 关系。

这是两张表:

                     posts table
_________________________________________________________________
| id | title | content | category_id | post_order  | post_active |                                        
|____|_______|_________|_____________|_____________|_____________|
| 1  | test1 | testing |     1       |       0     |      1      |
| 2  | test2 | testing |     1       |       1     |      1      |
| 3  | test3 | testing |     2       |       2     |      0      |
| .  | ..... | ....... |     .       |       .     |      .      |
|____|_______|_________|_____________|_____________|_____________|


       categories table
_____________________________________
| c_id | c_name | c_order | c_active |                                       
|______|________|_________|__________|
|   1  |  cat1  |    0    |    1     |
|   2  |  cat2  |    1    |    1     |      
|   3  |  cat3  |    2    |    0     |  
| .    | .....  | ....... |    .     |      
|______|________|_________|__________|

category_idc_id 之间存在关系,因此posts 表中的category_id 指的是类别id c_id

post_orderc_order 用于订购postscategories

post_activec_active用于定义是否显示给用户,1表示是显示,0表示否。

我将categoriesposts 显示在它们下方,例如:

________________________________________
|                 |          |          |
|    cat1         |   cat2   |   cat3   |
|  (active)       |__________|__________|
|                                       |
|                                       |
|    test1                              |
|        testing                        |
|                                       |
|    test2                              |
|        testing                        |
|_______________________________________|

显示数据的代码:

//That query should get the active categories and posts ordered by the order column, Not sure if it's correct. 
$results = $conn->prepare("SELECT * FROM categories LEFT JOIN categories ON categories.c_id = posts.id WHERE categories.c_active = '1' and posts.post_active = '1' order by categories.c_order, posts.post_order ASC");

//Execute the previous query.
$results->execute();

while ($row = $results->fetch(PDO::FETCH_ASSOC)) {
    $categories[$row['category_name']][] = $row;
}

//Print the categories
foreach (array_keys($categories) as $category_name) {
    echo $category_name;
}

//Print the posts
foreach ($categories as $category_name => $posts) { 
    foreach ($posts as $post) { 
        echo $post['title'];
    }
}

之前的 PHP 代码中有 HTML 代码用于为每个帖子创建选项卡和手风琴,如果有帮助,这里是完整代码:

<!-- Nav tabs -->
<ul class="nav nav-tabs" role="tablist">
    <?php foreach (array_keys($categories) as $category_name) { ?>
        <li role="presentation"><a href="#<?php echo str_replace(' ', '', $category_name); ?>" aria-controls="<?php echo str_replace(' ', '', $category_name); ?>" role="tab" data-toggle="tab"><?php echo $category_name; ?></a></li>
    <?php } ?>
</ul> <!-- .nav-tabs -->

<!-- Tab panes -->
<div class="tab-content">
    <?php foreach ($categories as $category_name => $posts) { ?>
        <div role="tabpanel" class="tab-pane fade" id="<?php echo str_replace(' ', '', $category_name); ?>">
            <div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true"> 
                <?php foreach ($posts as $post) { ?>
                    <div class="panel panel-default">
                        <div class="panel-heading" role="tab" id="headingOne">
                            <h4 class="panel-title">
                                <a role="button" class="collapsed" data-toggle="collapse" data-parent="#accordion" href="#<?php echo $post['id']; ?>_faq" aria-expanded="false" aria-controls="#<?php echo $post['id']; ?>_faq">
                                    <?php echo $post['title'] ?>
                                </a>
                            </h4>
                        </div>
                        <div id="<?php echo $post['id']; ?>_faq" class="panel-collapse collapse" role="tabpanel" aria-labelledby="headingOne">
                            <div class="panel-body">
                                <?php echo $post['content']; ?>
                            </div> <!-- .panel-body -->
                        </div> <!-- .panel-collapse -->
                    </div> <!-- .panel-default -->
                <?php } ?>  
            </div> <!-- .panel-group -->
        </div> <!-- .tab-pane -->
    <?php } ?>
</div> <!-- .tab-content -->

我应该得到所有活跃的categoriesposts,但我只得到第一个活跃的类别及其帖子。

【问题讨论】:

  • 您确定您的查询是更新的吗?
  • 您的查询看起来不对:SELECT * FROM categories LEFT JOIN categories ON categories.c_id = posts.id 应该是 SELECT * FROM categories LEFT JOIN posts ON categories.c_id = posts.category_id
  • 这是现在的查询SELECT * FROM categories LEFT JOIN posts ON c_id = posts.category_id WHERE category_active = 1 AND posts.post_active = 1 ORDER BY category_order AND posts.post_order ASC
  • 但我仍然只得到一个类别
  • 旁白:在ORDER BY 中将AND 替换为,;和ASC 不是必需的。你能为我们构建一个我们可以玩的 dbfiddle.com 演示吗?当问题全部解决并准备好编写代码时,提供支持总是更简单。

标签: php mysql sql pdo


【解决方案1】:

我会推荐这个查询:

SELECT b.c_name, a.id, TRIM(a.title) AS title, a.content
FROM posts a
INNER JOIN categories b ON a.category_id = b.c_id
WHERE a.post_active = '1' AND b.c_active = '1'
ORDER BY b.c_order, a.post_order
  • 与其要求 php 修剪标题,不如在查询中修复它。
  • 我正在使用INNER JOIN,因为我希望posts 中的所有行在categories 中都有相应的行。
  • c_orderpost_order 排序,以便在迭代结果集时将分类条目组合在一起。

基于我的演示:http://sqlfiddle.com/#!9/4ca1a1/3

并引用fetchAllFETCH_GROUP...

$resultset = fetchAll(PDO::FETCH_GROUP);
/* should generate:
    $resultset = [
        "social" => [
            ["id" => 5, "title" => "fifth title", "content" => "fifth content"],
            ["id" => 4, "title" => "fourth title", "content" => "fourth content"],
            ["id" => 2, "title" => "second title", "content" => "second content"]
        ],
        "tech" => [
            ["id" => 1, "title" => "first title", "first content"]
        ]
    ];
*/

您的类别位于array_keys($resultset)

您可以迭代准备好的结果集并访问第一级键和子数组行以显示数据。

【讨论】:

  • 谢谢你照常工作,代码变成$results-&gt;execute(); $results = $results-&gt;fetchAll(PDO::FETCH_GROUP); foreach (array_keys($results) as $category_name) { echo $category_name; } foreach ($results as $category_name =&gt; $posts) { foreach ($posts as $post) { echo $post['title']; } }
【解决方案2】:

您的查询必须是这样的:

SELECT * FROM `posts` `p`
LEFT JOIN `categories` `c` ON `c`.`c_id` = `p`.`category_id`
WHERE `c`.`c_active` = '1'
    and `p`.`post_active` = '1'
order by `p`.`post_order`, `c`.`c_order`

**然后执行查询并放入数组**

$myArr = array();
foreach($youQuery as $key => $val){
    $myArr[$val->c_id]['c_id '] = $val->c_id;
    $myArr[$val->c_id]['c_name '] = $val->c_name;
    $myArr[$val->c_id]['post '][$val->id]['id] = $val->id;
    $myArr[$val->c_id]['post '][$val->title ]['title ] = $val->title ;

    $i++;
}

然后你可以随意循环数组。

【讨论】:

  • 你拼错了foreach。为什么要声明$i$key?为了记录,这些反引号都不是必需的。键中的间距和缺少的单引号破坏了您的 sn-p。
  • 删掉,你觉得不对的,我只是给你做例子。
  • 不用了,谢谢。我会让你整理自己的帖子。
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2019-10-31
相关资源
最近更新 更多