【问题标题】:Merge arrays from 2 SQL results合并来自 2 个 SQL 结果的数组
【发布时间】:2011-03-26 12:23:22
【问题描述】:

所以我在 SQL 中有一个标签表设置

列表、列表标签、标签

每个列表可以有多个标签,标签有流派和制片人两种。现在,如果我们正在寻找所有带有标签“动作”的列表,这些是我正在遵循的步骤

SELECT GROUP_CONCAT(mini_lists_tags.list_id) AS list_ids
FROM (`mini_tags`)
LEFT JOIN `mini_lists_tags` ON `mini_lists_tags`.`tag_id` = `mini_tags`.`tag_id`
WHERE `mini_tags`.`tag_slug` = 'action'  

这将为列表的 id 返回一个数组 1,2。

SELECT *
FROM (`mini_lists_anime`)
JOIN `mini_lists` ON `mini_lists`.`list_id` = `mini_lists_anime`.`list_id`
WHERE `mini_lists`.`list_id` IN ('1', '2') 
AND `mini_lists`.`list_state` = 'active'

获取数组中的所有列表示例:

Array
(
    [0] => stdClass Object
        (
            [list_id] => 1
            [list_episodes] => 13
            [list_duration] => 24
            [list_aired] => 1238623200
            [list_age_rate] => PG-13 - Teens 13 or older
            [user_id] => 1
            [list_mal] => 5342
            [list_category] => Anime
            [list_type] => TV
            [list_status] => Completed
            [list_title] => Asura Cryin'
            [list_alt_titles] => アスラクライン
            [list_thumb] => 17071
            [list_likes] => 0
            [list_date] => 1300609723
            [list_update] => 0
            [list_state] => active
            [list_info] => 
        )

    [1] => stdClass Object
        (
            [list_id] => 2
            [list_episodes] => 26
            [list_duration] => 23
            [list_aired] => 1238623200
            [list_age_rate] => PG-13 - Teens 13 or older
            [user_id] => 1
            [list_mal] => 329
            [list_category] => Anime
            [list_type] => TV
            [list_status] => Completed
            [list_title] => Planetes
            [list_alt_titles] => プラネテス
            [list_thumb] => 4822
            [list_likes] => 0
            [list_date] => 1300609723
            [list_update] => 0
            [list_state] => active
            [list_info] => 
        )

)

然后我们得到标签

SELECT `mini_lists_tags`.`list_id`, `mini_tags`.`tag_type`, GROUP_CONCAT(mini_tags.tag_name) AS tag_names
FROM (`mini_lists_tags`)
INNER JOIN `mini_tags` ON `mini_tags`.`tag_id` = `mini_lists_tags`.`tag_id`
WHERE `mini_lists_tags`.`list_id` IN ('1', '2') 
GROUP BY `mini_lists_tags`.`list_id`, `mini_tags`.`tag_type`  

获取数组中的所有标签示例:

Array
(
    [0] => stdClass Object
        (
            [list_id] => 1
            [tag_type] => Genre
            [tag_names] => Supernatural,Action,Mecha
        )

    [1] => stdClass Object
        (
            [list_id] => 1
            [tag_type] => Producers
            [tag_names] => Seven Arcs
        )

    [2] => stdClass Object
        (
            [list_id] => 2
            [tag_type] => Genre
            [tag_names] => Romance,Action,Sci-fi,Comedy,Slice of Life,Drama,Space
        )

    [3] => stdClass Object
        (
            [list_id] => 2
            [tag_type] => Producers
            [tag_names] => Sunrise,Bandai Entertainment,Bandai Visual,Bang Zoom! Entertainment
        )

)

现在的问题是我需要将它们合并到 list_id 上,这样它就会为每个返回类似这样的内容。

    stdClass Object
    (
        [list_id] => 1
        [list_episodes] => 13
        [list_duration] => 24
        [list_aired] => 1238623200
        [list_age_rate] => PG-13 - Teens 13 or older
        [user_id] => 1
        [list_mal] => 5342
        [list_category] => Anime
        [list_type] => TV
        [list_status] => Completed
        [list_title] => Asura Cryin'
        [list_alt_titles] => アスラクライン
        [list_thumb] => 17071
        [list_likes] => 0
        [list_date] => 1300609723
        [list_update] => 0
        [list_state] => active
        [list_info] => 
        [list_tags] => Array
            (
                [0] => stdClass Object
                    (
                        [tag_type] => Genre
                        [tag_names] => Mecha,Action,Supernatural
                    )

                [1] => stdClass Object
                    (
                        [tag_type] => Producers
                        [tag_names] => Seven Arcs
                    )

            )

)

感谢任何建议,我真的迷路了。如果有比这更好的解决方案,我会全力以赴。

【问题讨论】:

    标签: php sql codeigniter multidimensional-array


    【解决方案1】:

    您可以执行另一种类型的联接,该联接将多次返回与每个子对象合并的父项,如下所示:

    Array(
       [0] => stdClass Object
        (
            [list_id] => 1
            [list_episodes] => 13
            [list_duration] => 24
            ...etc
            [tag_type] => Genre
            [tag_names] => Supernatural,Action,Mecha
            ...etc
        )
       [1] => stdClass Object
        (
            [list_id] => 1
            [list_episodes] => 13
            [list_duration] => 24
            ...etc
            [tag_type] => Producers
            [tag_names] => Seven Arcs
            ...etc
        )
       [2] => stdClass Object
        (
            [list_id] => 2
            [list_episodes] => 26
            [list_duration] => 23
            ...etc
            [tag_type] => Genre
            [tag_names] => Supernatural,Action,Mecha
            ...etc
        )
       [3] => stdClass Object
        (
            [list_id] => 2
            [list_episodes] => 26
            [list_duration] => 23
            ...etc
            [tag_type] => Producers
            [tag_names] => Seven Arcs
            ...etc
        )
    )
    

    然后,您需要遍历您的结果,将结果合并到他们的子/父关系中。这是因为 SQL 总是将行作为结果返回,而不是复杂的结构。

    虽然处理起来更复杂,但它通常比为每个父对象进行循环 sql 查询(称为 n+1 查询)的过程密集度更低

    【讨论】:

    • 谢谢你,知道如何在 php 中“合并结果”吗?
    • 可能最简单的方法是创建 2 个数组,一个是剧集,一个是流派。遍历上面查询中的每一行,并从该行创建一个新的剧集对象,并将其添加到剧集数组中。然后在这个循环中,遍历现有类型的数组(开始时为空)。如果第二个数组中没有任何类型与行中的类型匹配,则创建一个新类型并将其添加到该数组中。然后将当前剧集对象的流派属性分配给流派对象(创建的新对象或匹配的现有对象)。
    • 如果你想要更少循环;) 你可以将流派添加到第二个数组中,由它的 id 索引,而不是仅仅将它推到最后。然后您只需查看是否存在按索引匹配 id 的现有流派对象。
    猜你喜欢
    • 2017-01-31
    • 1970-01-01
    • 1970-01-01
    • 2016-07-19
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-16
    相关资源
    最近更新 更多