Matthew Woodard
Matthew Woodard

Reputation: 754

How to do MySQL Join and use PHP to get the values

I am trying to write a mysql query to pull data in this format:

<table>
    <caption>table title and/or explanatory text</caption>
    <thead>
        <tr>
            <th>User ID</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Field Name 1</th>
            <th>Field Name 2</th>
            <th>Field Name 3</th>
            <th>Field Name 4</th>
            <th>Field Name 5</th>
        </tr>
    </thead>
    <tbody>
    <?php 

        while ($row = mysqli_fetch_array($query)) {

        echo "<tr>
                <td>" .$row{'user_id'}. "</td>
                <td>" .$row{'first_name'}. "</td>
                <td>" .$row{'last_name'}. "</td>
                <td>" .$row{'field_name_1'}. "</td>
                <td>" .$row{'field_name_2'}. "</td>
                <td>" .$row{'field_name_3'}. "</td>
                <td>" .$row{'field_name_4'}. "</td>
                <td>" .$row{'field_name_5'}. "</td>
            </tr>";
        }
    ?>
    </tbody>
</table>

The tables in the database are formatted like the following.

Table: user_data

user_id      |     first_name     |    last_name     |
------------------------------------------------------
1            |     Jeff           |    Smith         |
------------------------------------------------------
2            |     Bob            |    Smith         |
------------------------------------------------------
3            |     Steve          |    Smith         |
------------------------------------------------------
4            |     Mary           |    Smith         |
------------------------------------------------------
5            |     Anna           |    Smith         |
------------------------------------------------------

Table: custom_fields

custom_field_id   |    name         |
-------------------------------------
3                 |    field name   |
-------------------------------------
5                 |    field name   |
-------------------------------------
7                 |    field name   |
-------------------------------------
9                 |    field name   |
-------------------------------------
11                |    field name   |
-------------------------------------

Table: custom_field_data

user_id      |     custom_field_id    |    value     |
------------------------------------------------------
1            |     3                  |    XXXX      |
------------------------------------------------------
1            |     5                  |    BBBB      |
------------------------------------------------------
1            |     7                  |    CCCC      |
------------------------------------------------------
1            |     9                  |    ZZZZ      |
------------------------------------------------------
1            |     11                 |    YYYY      |
------------------------------------------------------
2            |     3                  |    XXXX      |
------------------------------------------------------
2            |     5                  |    BBBB      |
------------------------------------------------------
2            |     7                  |    CCCC      |
------------------------------------------------------
2            |     9                  |    ZZZZ      |
------------------------------------------------------
3            |     3                  |    XXXX      |
------------------------------------------------------
3            |     5                  |    BBBB      |
------------------------------------------------------
3            |     9                  |    ZZZZ      |
------------------------------------------------------
3            |     11                 |    YYYY      |
------------------------------------------------------

I am looking for the best solution for querying the data and then printing it to the screen using PHP or AJAX. Is this possible? Would it be better to use json? And a sample query would be great.

FYI: In the long run all the data being extracted will need to be filtered on the screen. Thanks for the help.

My desired output would be

user_id      |     first_name     |    last_name     |  custom_field_3  |   custom_field_5  |   custom_field_7  |   custom_field_9  |   custom_field_11     |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
1            |     Jeff           |    Smith         |  XXXX            |   BBBB            |   CCCC            |   ZZZZ            |   YYYY                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
2            |     Bob            |    Smith         |  XXXX            |   BBBB            |   CCCC            |   ZZZZ            |   YYYY                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
3            |     Steve          |    Smith         |  XXXX            |   BBBB            |   CCCC            |   ZZZZ            |   YYYY                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
4            |     Mary           |    Smith         |  XXXX            |   BBBB            |   CCCC            |   ZZZZ            |   YYYY                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------
5            |     Anna           |    Smith         |  XXXX            |   BBBB            |   CCCC            |   ZZZZ            |   YYYY                |
-------------------------------------------------------------------------------------------------------------------------------------------------------------

Upvotes: 3

Views: 139

Answers (4)

chris85
chris85

Reputation: 23880

You can use the group_concat function, https://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat, with my previous query to get a single record per user...

If you had a SQLfiddle I could test this out but as is I don't have any data to test with...

select ud.firstname, ud.lastname, group_concat(cf.name) 
from user_data as ud 
join custom_field_data as cfd 
on cfd.user_id = ud.user_id 
join custom_fields as cf 
on cf.custom_field_id = cfd.custom_field_id

I tested this on 3 tables I have with a similar setup so I think it should work; names may need to be tweaked.

Update:

select ud.firstname, ud.lastname, group_concat(cf.name) 
from user_data as ud 
join custom_field_data as cfd 
on cfd.user_id = ud.user_id 
join custom_fields as cf 
on cf.custom_field_id = cfd.custom_field_id
group by ud.user_id

Upvotes: 3

Junius L
Junius L

Reputation: 16142

it is possible o pull the data with $.ajax() and PHP. Create a file data.php we are going to load this file with ajax. In your data.php file write this code.

$query = mysqli_query("select * from custom_field_data 
         inner join 
         user_data on user_data.user_id = custom_field_data.user_id
         inner join 
         custom_fields on custom_field_data.custom_field_id = custom_fields.custom_field_id");
<table>
<caption>table title and/or explanatory text</caption>
<thead>
    <tr>
        <th>User ID</th>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Field Name 1</th>
        <th>Field Name 2</th>
        <th>Field Name 3</th>
        <th>Field Name 4</th>
        <th>Field Name 5</th>
    </tr>
</thead>
<tbody>
 <?php 

    while ($row = mysqli_fetch_array($query)) {

    echo "<tr>
            <td>" .$row{'user_id'}. "</td>
            <td>" .$row{'first_name'}. "</td>
            <td>" .$row{'last_name'}. "</td>
            <td>" .$row{'field_name_1'}. "</td>
            <td>" .$row{'field_name_2'}. "</td>
            <td>" .$row{'field_name_3'}. "</td>
            <td>" .$row{'field_name_4'}. "</td>
            <td>" .$row{'field_name_5'}. "</td>
        </tr>";
    }
?>
</tbody>

In your main page use a button to load the data.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
 <script type="text/javascript">
$(function(){
    $('#load-data').click(function(){
        $.post('data.php', function(data){
            $('#results').html(data);
        });
    });
});
</script>

example on sqlfiddle

Upvotes: 1

Bulat
Bulat

Reputation: 6979

Lets start with simple join of your custom_field_data to user_data table where values and field names are hardcoded:

SELECT 
 u.*,
 f1.value as "<Field 1 Name>",
 ...
 f2.value as "<Field N Name>"
FROM 
 user_data u LEFT JOIN 
 custom_field_data f1 ON u.user_id = f1.user_id AND f1.custom_field_id = 1
 LEFT JOIN
 custom_field_data f ON u.user_id = fn.user_id AND fn.custom_field_id = <N>

Now, if you want to extract data without hardcoding, you will need to build your SQL dynamically based on data in custom_fields table:

SELECT * FROM custom_fields;

If some of your custom fields are never used in relation to users you would want to limit the number of custom fields like this:

SELECT * FROM custom_fields f
WHERE EXISTS 
       (SELECT * FROM custom_field_data 
        WHERE f.custom_field_id = custom_field_id)

Finally, to build required SQL in PHP you need these string sections:

// Begin SELECT clause (static):
$sql = "SELECT u.*,"

// Add all fields that you selected form the custom_fields:
foreach ($result as $row) { // Don't forget to handle commas
  $sql = $sql + <expression that gets codes and name>
}

// Start FROM clause (static):
$sql = $sql + " FROM user_data u "


// Join to custom_field_data:
foreach ($result as $row) {
  $sql = $sql + " LEFT JOIN custom_field_data <alias expression> ON ..
}

In the end you should get a string with SQL, that will join users to custom_field_data for each available custom field.

Upvotes: 1

Manju
Manju

Reputation: 728

The best way in my opinion is to use join because it will reduce the size of data transferred between DB and PHP

You can use JSON as it is light weight.

You can keep the things hidden in hidden field and use that for further filtering in client side completely

update --

For Sql server I would have written a query like this

select 
  t1.user_name,
  t1.first_name,
  t1.last_name,
  (select name from custom_fields 
   where custom_field_id= t2.custom_field_id) 
from
 user_data t1 left join
 custom_field_data t2 on t1.user_id=t2.userid

Change this according to my-sql

Upvotes: -2

Related Questions