Toniq
Toniq

Reputation: 5006

Mysql get results from one table based on another with join

I have 2 tables:

$sql = "CREATE TABLE $media_table (
            `id` int(11) NOT NULL AUTO_INCREMENT,
            `type` varchar(50) NOT NULL,
            `title` varchar(255) DEFAULT NULL,
            `description` varchar(2000) DEFAULT NULL,
            `playlist_id` int(11) NOT NULL,
            PRIMARY KEY (`id`),
            INDEX `playlist_id` (`playlist_id`),
        ) $charset_collate;";

$sql = "CREATE TABLE $taxonomy_table (
                `id` int(11) NOT NULL AUTO_INCREMENT,
                `type` varchar(10) NOT NULL,
                `title` varchar(500) NOT NULL,
                `media_id` int(11) NOT NULL,
                `playlist_id` int(11) NOT NULL,
                PRIMARY KEY (`id`),
                INDEX `media_id` (`media_id`),
                CONSTRAINT `mvp_taxonomy_ibfk_1` FOREIGN KEY (`media_id`) REFERENCES {$media_table} (`id`) ON DELETE CASCADE ON UPDATE CASCADE
            ) $charset_collate;";

Let say I want to select all rows from media_table where playlist_id=5 and title from taxonomy_table="sport, football".

I could run 2 queries, first get all media_id from taxonomy_table where title="..." AND playlist_id="5", then second query select all rows from media_table WHERE id IN (ids).

Does this belongs to some kind of JOIN query maybe?

I tried this but I am not getting desired results:

$query = "SELECT * FROM {$media_table} 
        INNER JOIN {$taxonomy_table} 
        ON {$media_table}.id = {$taxonomy_table}.media_id 
        WHERE {$taxonomy_table}.type='tag' AND {$taxonomy_table}.title IN ($arg) AND {$taxonomy_table}.playlist_id=%d
        ORDER BY {$media_table}.order_id";

It seems like its mixing all columns from both tables into the results, but I only want to retrieve rows from media_table that have title(s) from taxonomy_table.

Upvotes: 0

Views: 45

Answers (2)

asattler
asattler

Reputation: 59

It seems like its mixing all columns from both tables into the results, but I only want to retrieve rows from media_table that have title(s) from taxonomy_table.

Reason is that the join enables you to select data from both tables. The trick in this case is to change the asterisk (*) to specific columns or to use a prefix for the asterisk.

examples for using a prefix:

$query = "SELECT {$media_table}.* FROM {$media_table} 
INNER JOIN {$taxonomy_table} 
ON {$media_table}.id = {$taxonomy_table}.media_id 
    `WHERE {$taxonomy_table}.type='tag' AND {$taxonomy_table}.title IN ($arg) AND` {$taxonomy_table}.playlist_id=%d
ORDER BY {$media_table}.order_id";

or

$query = "SELECT t1.* FROM {$media_table} t1
INNER JOIN {$taxonomy_table} t2
ON t1.id = t2.media_id 
WHERE t2.type='tag' AND t2.title IN ($arg) AND t2.playlist_id=%d
ORDER BY t1.order_id";

UPDATE: You've raised two "new" question in the comment: From your use-cases I don't see any reason for using a join here.

1: retrieve rows from media_table that have ALL required title(s) from taxonomy_table

From my point of view there is no simple solution with just using SQL (except maybe really hacky string-operations in SQL). Easiest solution might be something like this:

$countTitles = count(explode(",", $args))
$query = "SELECT media_id from {$media_table} WHERE $countTitles = (
SELECT count(media_id) from {$taxonomy_table} WHERE type='tag' AND title IN ($arg) AND playlist_id=%d
)"

2: retrieve rows from media_table that ANY required title(s) from taxonomy_table.

This is just a simple in-clause.

$query = "SELECT * FROM {$media_table}
WHERE media_id IN (
SELECT media_id FROM {$taxonomy_table} WHERE type='tag' AND title IN ($arg) AND playlist_id=%d
)
";

Upvotes: 2

urs_ng
urs_ng

Reputation: 33

use a union instead of join with a nested / join query

    $query = "SELECT * FROM {$media_table} 
            INNER JOIN {$taxonomy_table} 
            ON {$media_table}.id = {$taxonomy_table}.media_id 
            WHERE {$taxonomy_table}.type='tag' AND {$taxonomy_table}.title IN ($arg) AND {$taxonomy_table}.playlist_id=%d
            ORDER BY {$media_table}.order_id 
union SELECT * FROM {$media_table}
WHERE media_id IN (
SELECT media_id FROM {$taxonomy_table} WHERE type='tag' AND title IN ($arg) AND playlist_id=%d
)
";

Upvotes: 0

Related Questions