开发者

Merge arrays from 2 SQL results

So i have a tags table setup in SQL

lists, lists_tags, tags

Each list can have multiple tags, and tags have two types genre and producer. Now if we are looking for all lists with tags 'action' these are the steps im following

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'  

That will return an array 1,2 for the ids of the list.

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'

that gets all the lists in an array EXAMPLE:

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
     开发者_如何学JAVA       [list_update] => 0
            [list_state] => active
            [list_info] => 
        )

)

And then we get the tags

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`  

that gets all the tags in an array EXAMPLE:

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
        )

)

Now the problem is I need to get them merged on the list_id so it returns something like this for each one.

    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
                    )

            )

)

Any advice is appreciated, i'm really lost. if there is better solution than this, i am all ears.


You can do another type of join that will return the parent item multiple times merged with each child object like so:

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
    )
)

You will then need to loop through your results merging down the results into their child/parent relationships. This is because SQL always returns rows as results, not complex structures.

Although this is more complex to deal with, it's ususally less process intensive than making looped sql queries for each parent object (known as n+1 queries)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜