简体   繁体   中英

Select multiple values for 1 user via PHP from SQL

EXPLAINATION

I have table with users and another table where stored certificates with user id's. 1 user can have multiple certificates. I need to select user once and list all of certificates by user id, but I can't achieve It correctly, selecting only 1 certificate for 1 user.

SAMPLE DATA

This very simplified sample data, for reality there are over 150 fields and 5 tables.

I have following tables:

Users

Id   FirstName   LastName 
1    John        Smith 
2    Lisa        Washington  

Certificates

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

PHP looks like:

$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 
    } 
    ?>

OUTPUT FOR NOW

If I pass GetUserId = 1 I got results:

John Smith 
Foo

DESIRED OUTPUT

It should list all of certificates for specific user.

John Smith 
Foo
Bar
Something

WHAT I'VE TRIED

I've tried to use foreach loop inside while loop, to get certificates, but in this way It didn't selected any certificates at all. Have you any ideas how can I achieve It?

This should work, you might have to change the separator in something else that you prefer.

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

Edit: Based on correct comment from @Matei Mihai that you should bind parameters instead of putting them in the query which is sql-injectable

$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();

Try this:

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

to get this OUTPUT-1 :

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

The output setup you have would output a multiple copies of John Smith, like so:

John Smith 
Foo
John Smith
Bar
John Smith
Something

If what you want is

John Smith 
Foo
Bar
Something

Then you need to either read your query into an array first before output:

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

Or break it up into 2 queries, which I'll leave for someone else to explain if you need it.

Something like this should work. I used structured programming and mysqli syntax, but I'm sure you can work with that.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM