1

I've scoured the internet, yet I couldn't find something like my problem. I'm trying to build a live search function that can pull data from multiple tables. It works with one table, but I want to be able to pull from bands, users, (albums, etc.)

Here's my PHP code:

require ("includes/config/config.php"); 

$search_term = sanitize(htmlentities($_POST['search_term']));

if (!empty($search_term)){

    $search = "(SELECT `band_id`, `band_name` FROM `bands` WHERE `band_name` LIKE '%$search_term%'  LIMIT 0, 5) 
                UNION ALL
                (SELECT `user_id`, `username` FROM `users` WHERE `username` LIKE '%$search_term%'  LIMIT 0, 5)";
    $query = mysqli_query($conn, $search);
    $result = mysqli_num_rows($query);

    while ($row = mysqli_fetch_assoc($query)){
        #$user_id = $row['user_id'];
        #$username = $row['username'];
        $band_id = $row['band_id'];
        $band_name = $row['band_name'];
        $check = mysqli_num_rows($query);



        if ($check != 0){
            echo "<a style='text-decoration: none; color: black;' href='index.php?band=$band_id'><li class='searchResults'>" . ucfirst($band_name) . "</li></a>";
        } else {
            echo "<li class='searchResults'>No Results Found</li>";
        }
    }
}

jQuery:

$("#searchbar").keyup(function(){
    var searchTerm = $(this).val();

    $.post('search.php', { search_term: searchTerm}, function(data){

        $(".searchResults").html(data);
        $("#searchUl").css("display", "block");
    });
});

Again, everything else runs fine, but I don't know how to query multiple tables in a way so I can echo out the href differently (i.e. index.php?band=$band_id for band and index.php?user=$user_id for user.

1 Answer 1

1

The problem is that you are losing information whether a record is a band or a user by doing a UNION ALL. This puts records of different types into the same set and merges the columns band_id, user_id and band_name, username.

You could fix this in different ways:

  1. Create two separate queries. Then get all the results from the bands query and put them in an array and put all the results from the user query into a different array. Afterwards, echo the results of both arrays.

  2. Make MySQL tell you the type of each row. You can achieve this by changing your query like this:

    (
        SELECT `band_id` , `band_name` , "band" AS `type`
        FROM `bands`
        WHERE `band_name` LIKE '%$search_term%'
        LIMIT 0 , 5
    )
    UNION ALL (    
        SELECT `user_id` , `username` , "user" AS `type`
        FROM `users`
        WHERE `username` LIKE '%$search_term%'
        LIMIT 0 , 5
    )
    

    Your query result will now have an additional column called type which will contain either "band" or "user". Depending on the value of that column you can echo a different link.

    For example, you could extend your code like this:

    if($row["type"] === "band") {
        echo "somelink?band_id=" . $row["band_id"];
    } else {
        echo "somelink?user_id=" . $row["band_id"];
    }
    

    Note that in both cases you will need to read $row["band_id"] because the join will take the column name from the first part of the query. All user IDs will be in the band_id column.

Sign up to request clarification or add additional context in comments.

5 Comments

How would I use the second option in an "if statement" or "echo" it out?
I ended up going with the first option, but I ended up having to put it through two different while loops causing it to display all band results before users. Not a good fix obviously, but it is nice to have it work. It will be perfected one day. Thanks for the help.
@MitchMullvain If using the second solution, you can access the type with $row['type'].
@MitchMullvain I updated my answer to include some example code how you could use the second solution; I hope this makes it clearer.
Thanks a bunch for your help. It works beautifully now and your suggestion really reduced the code. I really appreciate your help.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.