PDO 在 while 循环内运行查询,仅显示 1 个结果

Posted

技术标签:

【中文标题】PDO 在 while 循环内运行查询,仅显示 1 个结果【英文标题】:PDO run query inside while loop showing only 1 result 【发布时间】:2017-10-28 11:59:54 【问题描述】:

我想获取类别和子类别。两个表都有不同的表。请看下表结构:

tbl_category

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

tbl_sub_category

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

我尝试过以下答案:

query inside while loop only shows 1 result

下面是我的代码:

<ul class="list-unstyled components">
    <p style="text-align: center;font-weight: 600">Categories</p>
    <?php
        $query = $conn->prepare('SELECT * FROM tbl_category');
        $query->execute();
        $i = 1;
        $firstResults = array();
        while ($row = $query->fetch(PDO::FETCH_ASSOC)) 
        $ID = $row['id'];
    ?>
    <li class="">
        <a href="#homeSubmenu<?php echo $i;?>" data-toggle="collapse" aria-expanded="false"><?php echo $row['cat_name']; ?></a>
        <?php 
            $querySub = $conn->prepare('SELECT * FROM tbl_sub_category WHERE cat_id=:cat_id');
            $querySub->execute(array(':cat_id' => $ID));
            while ($rowSub = $querySub->fetch(PDO::FETCH_ASSOC)) 
        ?>
        <ul class="collapse list-unstyled" id="homeSubmenu<?php echo $i;?>">
            <li><a href="?cat=Allgem&sub=Beschreibung"><?php echo $rowSub['sub_name']; ?></a></li>
        </ul>
        <?php  ?>
    </li>
    <?php $i++;  ?>
</ul>

请帮助我们!!!!

更新问题:

请看上面两个表的表关系。

【问题讨论】:

你应该使用 JOIN 什么? Both tables has different tables @ArtisticPhoenix 是的,两者都是不同的表 两个表之间应该有链接。回到你的实体关系图。我希望你有一个 @Akintunde - 表格之间有一个链接,c.id = sc.cat_id 显然。 【参考方案1】:

尝试这样的加入

SELECT
    c.name,
    sc.*,
    c.order_number
FROM
    tbl_sub_category AS sc
INNER JOIN
    tbl_category AS c ON c.id = sc.cat_id

你可以在这里测试这个 https://www.db-fiddle.com/f/vX8Z6jPbaweBDjGtvPwRdP/0

没有必要拉,c.id (无论如何它会模棱两可)并且你已经拥有它作为sc.cat_id。所以,我们真正需要的是子类别表中的所有内容(别名为sc,以及类别表中的类别名称和订单号(别名为c)。

如果您需要没有子类别的主要类别,那么您可以进行左连接。您必须考虑一些空值,无论如何都是这样。

SELECT
    c.name,
    sc.*,
    c.order_number
FROM
    tbl_category AS c
LEFT JOIN
     tbl_sub_category AS sc ON c.id = sc.cat_id

还有这个在这里 https://www.db-fiddle.com/f/kdgD9K5TYnD79boUdaC57k/0

我故意将子类别 6 和 7 排除在外,以展示左连接的工作原理,这样 cat 4 就没有任何子类别。如果您需要考虑这些问题,最好有一个合适的测试用例。

在您整理好查询后(一次调用而不是 On 次调用),您将遵循非常标准的过程,构建数据然后输出它。像这样:

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

首先要做的是按类别对数据进行分组,这样我们就可以有一个类别的项目和几个子类别的项目。类别名称$row['name'] 对此非常有用,因为我们需要在内部 foreach 循环之外使用它。 正如@YourCommonSense 所提到的,在cmets 中,我们可以通过使用PDO::FETCH_GROUP 并将name 列作为我们选择列表的第一列轻松地做到这一点。

这会给你这样的东西:

$data = [
    'Allgem' => [
        ['id'=>'1','cat_id'=>'1','sub_name'=>'Alter','name'=>'Allgem','order_number'=>'1'],
    ],
    'Vorauss' => [
        ['id'=>'2','cat_id'=>'2','sub_name'=>'Trainingsalter','name'=>'Vorauss','order_number'=>'2'],
        ['id'=>'3','cat_id'=>'2','sub_name'=>'Kader','name'=>'Vorauss','order_number'=>'2'],
        ['id'=>'4','cat_id'=>'2','sub_name'=>'Wettkampfsystem','name'=>'Vorauss','order_number'=>'2'],
    ],
    'Support' => [
        ['id'=>'5','cat_id'=>'3','sub_name'=>'Trainingsort','name'=>'Support','order_number'=>'3'],
        ['id'=>'6','cat_id'=>'3','sub_name'=>'Team','name'=>'Support','order_number'=>'3'],
    ]
];

如您所见,现在我们有一个按猫 ID 分组的结构。这对于我们接下来需要做的事情会更好。因为我们按照我们想要的方式对数据进行了预格式化,从而使我们的代码更简单、更简洁、更易于阅读。

<ul class="list-unstyled components">
    <p style="text-align: center;font-weight: 600">Categories</p>
    <?php
        $i = 0;
        foreach ($data as $cat_name => $sub_categories):
    ?>
        <li class="">
            <a href="#homeSubmenu<?php echo $i;?>" data-toggle="collapse" aria-expanded="false"><?php echo $cat_name ; ?></a>
            <?php foreach ($sub_categories as $row): ?>
                <ul class="collapse list-unstyled" id="homeSubmenu<?php echo $i;?>">
                    <li><a href="?cat=Allgem&sub=Beschreibung"><?php echo $row['sub_name']; ?></a></li>
                </ul>
            <?php endforeach; ?>
        </li>
    <?php
        $i++;
        endforeach;
    ?>
</ul>

您可以在这里对其进行测试,但几乎不可能找到一个允许您混合 html、PHP、保存并以 HTML 格式输出的 phpSandbox。所以它只是原始的源 html,但你可以看到它在语法上是正确的并且没有错误。

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

关于错误,您还遇到了其他几个问题。就像子链接有一个静态地址&lt;a href="?cat=Allgem&amp;sub=Beschreibung"&gt;。你有$row['cat_name'],它在你的表模式中不存在(它只是tbl_category.name。另一个是第一个&lt;ul&gt;&lt;li&gt; 之间的&lt;p&gt; 标签我没有看到一个合理的方法来解决这个问题而不改变结构,因为结构是问题。见下文:

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

我个人建议使用字典列表,或&lt;dl&gt;

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

这会让你做这样的事情

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

或者干脆删除&lt;p&gt; 标签?无论如何,您的原始 HTML 可能还有其他我没有看到的问题。但我认为这应该能让你走上正轨。

干杯。

【讨论】:

简单,然后左连接 所以事实上你只需要$data = $conn-&gt;query($sql)-&gt;fetchAll(PDO::FETCH_GROUP); @YourCommonSense - 在 php.net 网站上没有很好地介绍之前,我实际上从未使用过它。所以谢谢,每天学习新东西,6 年 PHP 并且从未注意到这一点。 满意(已删除)?我累了大约 27 小时,这在大范围内并不重要。但我只是想帮助 OP。 TBH,我很惊讶他还没有得到十亿的反对票。 仅供参考,我主要是自学成才,我责怪 php.net 网站缺乏有关该获取模式的文档。 php.net/manual/en/pdostatement.fetchall.php有半句之类的吗?

以上是关于PDO 在 while 循环内运行查询,仅显示 1 个结果的主要内容,如果未能解决你的问题,请参考以下文章

优化包含 PDO 查询的 while 循环

PDO 查询未在 PHP foreach 循环中返回结果

foreach 循环内的 while 循环仅返回 1 行

使用 PDO 驱动程序 PHP 在 sql-server 查询中循环

使用PDO执行基于另一个查询结果的查询的函数

循环更新查询 pdo where id