代码之家  ›  专栏  ›  技术社区  ›  Toniq

Mysql通过join从一个表中获取基于另一个表的结果

  •  0
  • Toniq  · 技术社区  · 7 年前

    我有两张桌子:

    $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;";
    

    假设我想从media\u table中选择所有行,其中playlist\u id=5,title来自taxonomy\u table=“sport,football”。

    我可以运行2个查询,首先从taxonomy\u table where title=“…”和playlist\u id=“5”中获取所有媒体\u id,然后第二个查询从media\u table where id IN(ids)中选择所有行。

    这可能属于某种连接查询吗?

    $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";
    

    它似乎将两个表中的所有列都混合到结果中,但我只想从media\u表中检索那些标题来自taxonomy\u表的行。

    2 回复  |  直到 7 年前
        1
  •  2
  •   asattler    7 年前

    它似乎将两个表中的所有列都混合到结果中,但我只想从media\u表中检索那些标题来自taxonomy\u表的行。

    原因是联接使您能够从两个表中选择数据。 在这种情况下,诀窍是将星号(*)更改为特定列或使用星号前缀。

    使用前缀的示例:

    $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";
    

    $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";
    

    更新: 您在评论中提出了两个“新”问题: 从您的用例中,我看不出有任何理由在这里使用连接。

    1:从媒体表中检索具有所有所需标题的行 分类表

    从我的观点来看,仅仅使用SQL并没有简单的解决方案(除了SQL中真正的hacky字符串操作)。

    $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:从媒体表中检索任何所需标题所在的行 分类表。

    这只是一个简单的in子句。

    $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
    )
    ";
    
        2
  •  0
  •   urs_ng    7 年前

    对嵌套/联接查询使用联合而不是联接

        $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
    )
    ";
    
    推荐文章