duanjian4150 2017-10-28 03:59
浏览 31
已采纳

PDO在内部运行查询,而循环只显示1个结果

I want to get categories and sub categories. Both tables has different tables. Please see the below table structures:

tbl_category

  1. id | name | order_number
  2. 1 | Allgem | 1
  3. 2 | Vorauss| 2
  4. 3 | Support| 3
  5. 4 | Zielste| 4

tbl_sub_category

  1. id | cat_id | sub_name
  2. 1 | 1 | Alter
  3. 2 | 2 | Trainingsalter
  4. 3 | 2 | Kader
  5. 4 | 2 | Wettkampfsystem
  6. 5 | 3 | Trainingsort
  7. 6 | 3 | Team
  8. 7 | 4 | Betreuung
  9. 8 | 4 | Unterstuetzung

I have tried with the below answer:

query inside while loop only shows 1 result

Below is my code:

  1. <ul class="list-unstyled components">
  2. <p style="text-align: center;font-weight: 600">Categories</p>
  3. <?php
  4. $query = $conn->prepare('SELECT * FROM tbl_category');
  5. $query->execute();
  6. $i = 1;
  7. $firstResults = array();
  8. while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
  9. $ID = $row['id'];
  10. ?>
  11. <li class="">
  12. <a href="#homeSubmenu<?php echo $i;?>" data-toggle="collapse" aria-expanded="false"><?php echo $row['cat_name']; ?></a>
  13. <?php
  14. $querySub = $conn->prepare('SELECT * FROM tbl_sub_category WHERE cat_id=:cat_id');
  15. $querySub->execute(array(':cat_id' => $ID));
  16. while ($rowSub = $querySub->fetch(PDO::FETCH_ASSOC)) {
  17. ?>
  18. <ul class="collapse list-unstyled" id="homeSubmenu<?php echo $i;?>">
  19. <li><a href="?cat=Allgem&sub=Beschreibung"><?php echo $rowSub['sub_name']; ?></a></li>
  20. </ul>
  21. <?php } ?>
  22. </li>
  23. <?php $i++; } ?>
  24. </ul>

Please help us guys!!!!

UPDATED QUESTION:

enter image description here

Please see the above table relationship of both tables.

展开全部

  • 写回答

1条回答 默认 最新

  • doufangmu9087 2017-10-28 04:08
    关注

    Try a Join like this

    1. SELECT
    2. c.name,
    3. sc.*,
    4. c.order_number
    5. FROM
    6. tbl_sub_category AS sc
    7. INNER JOIN
    8. tbl_category AS c ON c.id = sc.cat_id

    You can test this one here https://www.db-fiddle.com/f/vX8Z6jPbaweBDjGtvPwRdP/0

    There is no need to pull, c.id (it would be ambiguous, anyway ) and you already have it as sc.cat_id. So, what we really need is everything from the sub-category table (alias as sc) and just the category name and order_number from the category table (aliased as c).

    If you need main categories without a sub-category then you can do a Left Join. You'll have to account for some null values, which would be the case no matter what.

    1. SELECT
    2. c.name,
    3. sc.*,
    4. c.order_number
    5. FROM
    6. tbl_category AS c
    7. LEFT JOIN
    8. tbl_sub_category AS sc ON c.id = sc.cat_id

    And this one here https://www.db-fiddle.com/f/kdgD9K5TYnD79boUdaC57k/0

    I intentionally left sub-category 6 & 7 out, to show how it works for the left join, this way cat 4 doesn't have any sub-categories. It's a good Idea to have a proper test case if you need to account for those.

    After you get your query sorted out (one call instead of O{n} calls), you'd follow pretty standard procedure, structure the data then output it. Like so:

    1. <?php
    2. $data = $conn->query($sql)->fetchAll(PDO::FETCH_GROUP);
    3. ?>

    First thing to do is group the data by category, so we can have a item for category and several items for sub-categories. The category name $row['name'] works great for this, because we need it outside of the inner foreach loop. As mentioned by @YourCommonSense, in the comments, we can easily do this by using PDO::FETCH_GROUP and putting the name column as the first column in our selection list.

    Which will give you something like this:

    1. $data = [
    2. 'Allgem' => [
    3. ['id'=>'1','cat_id'=>'1','sub_name'=>'Alter','name'=>'Allgem','order_number'=>'1'],
    4. ],
    5. 'Vorauss' => [
    6. ['id'=>'2','cat_id'=>'2','sub_name'=>'Trainingsalter','name'=>'Vorauss','order_number'=>'2'],
    7. ['id'=>'3','cat_id'=>'2','sub_name'=>'Kader','name'=>'Vorauss','order_number'=>'2'],
    8. ['id'=>'4','cat_id'=>'2','sub_name'=>'Wettkampfsystem','name'=>'Vorauss','order_number'=>'2'],
    9. ],
    10. 'Support' => [
    11. ['id'=>'5','cat_id'=>'3','sub_name'=>'Trainingsort','name'=>'Support','order_number'=>'3'],
    12. ['id'=>'6','cat_id'=>'3','sub_name'=>'Team','name'=>'Support','order_number'=>'3'],
    13. ]
    14. ];

    As you can see, now we have a structure grouped by the cat ID. This will work much better for what we need to do next. Because we pre-format the data the way we want it makes our code simpler, more concise and easier to read.

    1. <ul class="list-unstyled components">
    2. <p style="text-align: center;font-weight: 600">Categories</p>
    3. <?php
    4. $i = 0;
    5. foreach ($data as $cat_name => $sub_categories):
    6. ?>
    7. <li class="">
    8. <a href="#homeSubmenu<?php echo $i;?>" data-toggle="collapse" aria-expanded="false"><?php echo $cat_name ; ?></a>
    9. <?php foreach ($sub_categories as $row): ?>
    10. <ul class="collapse list-unstyled" id="homeSubmenu<?php echo $i;?>">
    11. <li><a href="?cat=Allgem&sub=Beschreibung"><?php echo $row['sub_name']; ?></a></li>
    12. </ul>
    13. <?php endforeach; ?>
    14. </li>
    15. <?php
    16. $i++;
    17. endforeach;
    18. ?>
    19. </ul>

    You can test it here, but it's near impossible to find a phpSandbox that allows you to mix HTML, PHP, save it, and output in HTML. So it's just the raw source html, but you can see it's syntactically correct and error free.

    http://sandbox.onlinephpfunctions.com/code/1030bfd98c73d12b718077363d30ac587166c6cb

    On the topic of errors, you also had several other issues. Like the sub-link had a static address <a href="?cat=Allgem&sub=Beschreibung">. You had $row['cat_name'] which dosn't exist in your table schema (its just tbl_category.name). Another one is this <p> tag between the first <ul> and <li> I didn't see a reasonable way to fix that without changing the structure, because well the structure is the issue. See below:

    1. <ul class="list-unstyled components">
    2. <p style="text-align: center;font-weight: 600">Categories</p> <!-- p tags shouldn't be here -->
    3. ....
    4. <li class="">

    Personally, I would recommend using a dictionary list, or <dl>

    https://www.w3schools.com/tags/tag_dl.asp

    Which would let you do something like this

    1. <dl class="list-unstyled components">
    2. <dt><p style="text-align: center;font-weight: 600">Categories</p></dt
    3. <dd class=""><!-- instead of the li tag --></dd>
    4. </dl>

    Or just remove the <p> tag altogether? Anyway, there may be other issues with your original HTML that I didn't see. But I figure this should get you on the right track.

    Cheers.

    展开全部

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
编辑
预览

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部