简体   繁体   中英

Mixed result from MySQL Query, How to sort

I am querying a table called request that looks like this

+-------------------------------------------------------------------------+    
| message_id | client_id | admin_id | message | date_posted | read_status |
+-------------------------------------------------------------------------+

And as admin needs to get all the messages that are not read (read_status = 0) but I don't know how to get the result and display them into different tabs example

Client 44
Hi Sir

then a different section (div)

Client 87
Give me the number

So messages from the same client are put together and inserted into its own div

The thing is the same client can have multiple rows with different messages. Oh and for each row selected I want update the read_status to 1 so it doesn't get selected later on. Any help is much appreciated!

PS I'm using PDO to query with prepared statements to keep things clean!

If I understand correctly, you want a <div > for each client, where that <div> contains all unread messages for the client that <div> belongs to.

That would mean you need to group your results by client. There are two ways you could do that:

  1. Let MySQL sort the messages, and let PHP keep track of when the client_id changes so you can close the previous <div> and open a new one for the new client;
  2. Group the messages using PHP after fetching the messages, then loop through that.

For the first option, you could do something like this:

$current_client_id = 0;

foreach ($conn->query("SELECT ... ORDER BY `client_id` ASC") as $message) {
    if ($message['client_id'] != $current_client_id) {
        if ($current_client_id > 0) {
            // if it's 0, there is no <div> to close yet
            echo '</div>';
        }
        echo '<div>';
        echo '<p>Messages for client #' . $message['client_id'] . '</p>';
        $current_client_id = $message['client_id'];
    }

    echo 'message details here';
}

if ($current_client_id > 0) {
    // if it's not 0, there were messages so you need to
    // close the last client's <div>
    echo '</div>';
}

For the second option, you could do something like this:

$grouped_messages = array();

foreach ($conn->query("SELECT ...") as $message) {
    $client_id = $message['client_id'];

    if (!isset($grouped_messages[$client_id])) {
        $grouped_messages[$client_id] = array();
    }

    $grouped_messages[$client_id][] = $message;
}

foreach ($grouped_messages as $client_id => $client_messages) {
    echo '<div>';
    echo '<p>Messages for client #' . $client_id . '</p>';

    foreach ($client_messages as $message) {
        echo 'message details here';
    }

    echo '</div>';
}

The first option is more efficient, because you're only looping once. But in my personal opinion, the second option delivers cleaner, easier to read and understand code, so I'd prefer that if you're not dealing with a large number of messages, or if you're passing the array of messages to a separate view layer or template.

You'll have to fill in the query yourself, I don't know if you want to fetch all fields or only a few of them, sort it by date_posted , filter only messages with a certain admin_id or join the request table with another table for example.

I also didn't use a prepared statement, but you can replace the loops on $conn->query() with one quite easily:

$stmt = $conn->prepare("SELECT ...");
$stmt->execute();
foreach ($stmt->fetchAll() as $message) {

As long as you're not binding any parameters, PDO::query() is basically shorthand for exactly that.

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