【问题标题】:Select multiple values for 1 user via PHP from SQL通过 PHP 从 SQL 为 1 个用户选择多个值
【发布时间】:2016-03-30 07:40:48
【问题描述】:

解释

我有一个用户表和另一个表,其中存储了带有用户 ID 的证书。 1 个用户可以拥有多个证书。我需要选择一次用户并按用户 ID 列出所有证书,但我无法正确实现它,只为 1 个用户选择 1 个证书。

样本数据

这个非常简化的示例数据,实际上有超过 150 个字段和 5 个表。

我有以下表格:

用户

Id   FirstName   LastName 
1    John        Smith 
2    Lisa        Washington  

证书

UserId   CertificateName
1        Foo
1        Bar 
1        Something
2        FooBar
2        Bizz

PHP 看起来像:

$UserID = get_current_user_id();
$GetUserId = $_GET["Id"];
if(isset($UserID)) {    

    $users = $con->prepare("
    SELECT u.FirstName
           ,u.LastName
           ,c.CertificateName          
    FROM Users u
    LEFT JOIN Certificates c ON u.Id = c.UserID
    WHERE u.Id = '$GetUserId'
    LIMIT 1
    "); 

    $users->execute();

    $users->bind_result(        
        $FirstName,             
        $LastName,  
        $CertificateName
    );


} else {
    echo "There is no User ID detected, try to refresh browser.";   
}

<html>
....

    <?php 
    while ($users->fetch()) {
    ?>  
        <div class="grid-item"><?php echo $FirstName; ?></div>          
        <div class="grid-item"><?php echo $LastName; ?></div>
        <div class="certificates"><?php echo $CertificateName; ?></div>
    <?php 
    } 
    ?>

现在输出

如果我通过GetUserId = 1 我得到了结果:

John Smith 
Foo

期望的输出

它应该列出特定用户的所有证书。

John Smith 
Foo
Bar
Something

我的尝试

我尝试在 while 循环中使用 foreach 循环来获取证书,但是这样它根本没有选择任何证书。您有什么想法可以实现吗?

【问题讨论】:

  • 您的查询似乎很好,应该返回 john,bar 和一些东西,为什么它会返回 'Foo'?
  • 使用准备好的语句很好。错误地使用它们很糟糕..您应该在查询中使用绑定以避免 sql 注入:WHERE u.Id = :uid$users-&gt;execute(array('uid' =&gt; $GetUserId));

标签: php html mysql sql loops


【解决方案1】:

这应该可行,您可能需要将分隔符更改为您喜欢的其他内容。

SELECT u.FirstName,
       u.LastName,
       GROUP_CONCAT(c.CertificateName SEPARATOR '<br>') AS CertificateName         
FROM Users u
LEFT JOIN Certificates c ON u.Id = c.UserID
WHERE u.Id = '$GetUserId'
LIMIT 1

编辑: 根据@Matei Mihai 的正确评论,您应该绑定参数而不是将它们放入可注入 sql 的查询中

$users = $con->prepare("
SELECT u.FirstName,
       u.LastName,
       GROUP_CONCAT(c.CertificateName SEPARATOR '<br>') AS CertificateName         
FROM Users u
LEFT JOIN Certificates c ON u.Id = c.UserID
WHERE u.Id = ?
LIMIT 1
"); 
$users->bind_param('i',$GetUserId);
$users->execute();

【讨论】:

    【解决方案2】:

    试试这个:

    SELECT 
        * 
    FROM 
        Users usr
    INNER JOIN 
        Certificates cert
    ON 
        usr.Id = cert.UserId 
    WHERE 
        usr.Id = '1'
    

    要获得这个OUTPUT-1

    Id   FirstName   LastName  UserId   CertificateName
    1    John        Smith     1        Foo
    1    John        Smith     1        Bar 
    1    John        Smith     1        Something
    

    【讨论】:

    • 如果您想要在 POST 中显示的相同结果。 1. 迭代通过我的查询获取的结果。 2. 在 PHP 中创建另一个数组并构建逻辑以将获取的结果存储为所需的格式。 注意: 这样你就必须调用一次数据库(这听起来很有效)
    【解决方案3】:

    您的输出设置将输出 John Smith 的多个副本,如下所示:

    John Smith 
    Foo
    John Smith
    Bar
    John Smith
    Something
    

    如果你想要的是

    John Smith 
    Foo
    Bar
    Something
    

    然后您需要在输出之前先将查询读入数组:

    <?php 
        $certArray = array();
        while ($users->fetch()) {
            $certArray[] = $CertificateName;
        }
    ?>
            <div class="grid-item"><?php echo $FirstName; ?></div>          
            <div class="grid-item"><?php echo $LastName; ?></div>
    <?php
        foreach($certArray as $CertificateName) {
    ?>
            <div class="certificates"><?php echo $CertificateName; ?></div>
    <?php 
        } 
    ?>
    

    或者将其分解为 2 个查询,如果您需要,我将留给其他人解释。

    【讨论】:

    • 感谢您的回答,如果我试图从证书表中仅选择 $CertificateName,它会起作用。如果我加入 CertificatesDetails 表并尝试在以下选项中选择 $CertificateNoforeach($certArray as $CertificateName) { ?&gt; &lt;div class="certificates"&gt;&lt;?php echo $CertificateName; ?&gt;&lt;/div&gt; &lt;div class="certificates"&gt;&lt;?php echo $CertificateNo; ?&gt;&lt;/div&gt; &lt;?php } 我会为每个 CertificateName 重复相同的 CertificateNo
    【解决方案4】:

    这样的事情应该可以工作。我使用结构化编程和 mysqli 语法,但我相信你可以使用它。

    <?php
     //Assuming $con is your DB connector
    
    $q = 'SELECT * FROM Users';
    $r = mysqli_query($con, $q);
    
    while($list = mysqli_fetch_assoc($r)) { ?>  
      <tr>      
        <td><?php echo $list['id']; ?></td>
        <td><?php echo $list['FirstName']; ?></td>
        <td><?php echo $list['LastName']; ?></td>        
        <td>
        <?php 
        //echo the certificate names            
        $userId = $list['id'];                              
    
            $q1 = 'SELECT * from Certificates WHERE UserId = '.$userId.'';
            $r1 = mysqli_query($con, $q1);
    
            while($certif = mysqli_fetch_assoc($r1)){   
    
                echo $certif['CertificateName'].'<br /> ';          
            }               
    ?>
        </td>
     </tr>
    
    <?php }?>
    

    【讨论】:

      猜你喜欢
      • 2016-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多