Search code examples
phpmysqlwordpresswordpress-rest-api

How to join two MySQL tables for wp_rest_api


In my WordPress database I have three tables wp_companies which stores some company info and wp_product_types which stores a bunch of product types that a company can assign them selves then I have wp_company_products which is used to assign product types to a company using ids.

Heres an example of how the database looks:

wp_companies

id | company_name | member_type | logo
-----------------------------------------------------------------
1  | Google       | full        | https://via.placeholder.com/150
-----------------------------------------------------------------
2  | Crunchyroll  | full        | https://via.placeholder.com/150

wp_products

id | product_name    |
----------------------
1  | Car Insurance   |
----------------------
2  | House Insurance |
----------------------
3  | Life Insurance  |

wp_company_products

id | company_id | product_id 
----------------------------
1  | 1          | 2
----------------------------
2  | 2          | 1
----------------------------
3  | 1          | 3

Here's my current MySQL query that simply shows the data in wp_companies

    add_action('rest_api_init', function() {
        register_rest_route('custom-routes/v1', 'members', array(
            'methods' => 'GET',
            'callback' => 'get_members'
        ) );
    });

    function get_members($data) {
        global $wpdb;

        $query = $wpdb->get_results( "SELECT company_name, member_type, logo, site_url FROM {$wpdb->prefix}companies ORDER BY RAND()" );

        foreach ( $query as $member ) {
            $member_data[] = array(
                "company_name" => $member->company_name,
                "member_type" => $member->member_type,
                "logo" => $member->logo,
            );
        }

        return $member_data;
    }

This displays my data like so on my api end point:

[
    {
        "company_name":"Google",
        "member_type":"full",
        "logo":"https://via.placeholder.com/150",
    },
    {
        "company_name":"Crunchyroll",
        "member_type":"full",
        "logo":"https://via.placeholder.com/150",
    }
]

But what I want is to combine the wp_companies and wp_company_products tables so that my data is displayed something like this on the api end point:

[
    {
        "company_name":"Google",
        "member_type":"full",
        "logo":"https://via.placeholder.com/150",
        "products": [
            "House Insurance",
            "Life Insurance"
         ]
    },
    {
        "company_name":"Crunchyroll",
        "member_type":"full",
        "logo":"https://via.placeholder.com/150",
        "products": [
            "Car Insurance",
         ]
    }
]

How can I structure my MySQL query to be able to achieve this?


Solution

  • Please try this

    function get_members($data) {
        global $wpdb;
    
        $query = $wpdb->get_results( "SELECT company_name, member_type, logo, site_url FROM {$wpdb->prefix}companies ORDER BY RAND()" );
    
        foreach ( $query as $member ) {
            $productQuery = $wpdb->get_results( "SELECT product_name FROM wp_products WHERE id IN (SELECT product_id from wp_company_products WHERE compony_id = '{$member->id}') " );
            $products = array();
            foreach ( $productQuery as $prduct ) {
                array_push($products ,$prduct->product_name);
            }
    
            $member_data[] = array(
                "company_name" => $member->company_name,
                "member_type" => $member->member_type,
                "logo" => $member->logo,
                "products" => $products
            );
        }
    
        return $member_data;
    }