MySQL 按顺序查找每组最近/最大记录

标签 mysql query-optimization greatest-n-per-group

MySQL按顺序查找每组的最近/最大记录,以及如何最小化/缩短此查询以及每次它返回组的第一行值时,而我喜欢选择组的最后一行值,并根据 ja.id 对值进行排序?我知道这是一个糟糕的查询,任何人都可以建议或为我提供解决方案来缩短此查询。我已在所有表中使用了所有必要的列索引。 如何在不使用 union all 的情况下缩短查询。union all 中的查询与 where 语句中的查询相同。

SELECT
a.previous_status,
a.rejected_status,
a.rejection_reason_text,
a.rejection_reason,
a.rjaId,
a.refer_applied_status,
a.title,
a.playerId,
a.gameId,
a.gamePostDate,
a.game_referal_amount,
a.country,
a.country_name,
a.state,
a.location,
a.state_abb,
a.game_type,
a.appliedId,
a.appliedStatus,
a.admin_review,
a.is_req_referal_check,
a.memberId,
a.appliedEmail,
a.game_id,
a.referred_id,
a.memStateAbb,
a.memState,
a.memZipcode,
a.memCity,
a.memCountryNme,
a.memCountry,
a.appliedMemberName,
a.first_name,
a.primary_contact,
a.last_name,
a.addressbookImage,
a.userImage,
a.last_login,
a.user_experience_year,
a.user_experience_month,
a.current_designation,
a.current_player,
a.appliedDate,
a.addressbook_id,
a.joiningdate,
a.gameStatus,
a.gameReferalAmountType,
a.gameFreezeStatus,
a.gameFreezeMsg,
a.app_assign_back_to_rp_count,
a.applied_source,
a.max_id,
a.gamesApplied,
a.gamesAppliedId,
SUM(a.totalgameApplied) AS totalgameApplied,
a.application_assign_to_rp_status,
a.rpAppliedSource,
a.applied_on
                FROM
(
    (
        SELECT
            ja.previous_status,
            ja.rejected_status,
            ja.rejection_reason_text,
            ja.rejection_reason,
            rja.id AS rjaId,
            rja. STATUS AS refer_applied_status,
            jp.title,
            jp.user_user_id AS playerId,
            jp.id AS gameId,
            jp.posted_on AS gamePostDate,
            jp.game_referal_amount,
            jp.country,
            jp.country_name,
            jp.state,
            jp.location,
            jp.state_abb,
            jp.game_type,
            ja.id AS appliedId,
            IFNULL(ja. STATUS, '') AS appliedStatus,
            IFNULL(ja.admin_review, '') AS admin_review,
            ja.is_req_referal_check,
            usr.id AS memberId,
            rja.email AS appliedEmail,
            rja.game_id,
            rja.referred_id,
            mem.state_abb AS memStateAbb,
            mem.state AS memState,
            mem.zipcode AS memZipcode,
            mem.city AS memCity,
            mem.country_name AS memCountryNme,
            mem.country_code AS memCountry,
            usc. NAME AS appliedMemberName,
            usc.first_name,
            IFNULL(
                mem.primary_contact,
                usc.phone_number
            ) AS primary_contact,
            usc.last_name,
            usc.profileimage_path AS addressbookImage,
            usr.profile_image AS userImage,
            usr.last_login,
            mem.user_experience_year,
            mem.user_experience_month,
            mem.current_designation,
            mem.current_player,
            rja.create_date AS appliedDate,
            rja.addressbook_id,
            IFNULL(ja.joining_date, '') AS joiningdate,
            jp. STATUS AS gameStatus,
            jp.games_referal_amount_type AS gameReferalAmountType,
            jp.game_freeze_status AS gameFreezeStatus,
            jp.game_freeze_message AS gameFreezeMsg,
            ja.app_assign_back_to_rp_count,
            ja.applied_source,
            MAX(rja.id) AS max_id,
            GROUP_CONCAT(
                jp.title
                ORDER BY
                    rja.create_date DESC
            ) AS gamesApplied,
            GROUP_CONCAT(DISTINCT(jp.id)) AS gamesAppliedId,
            COUNT(DISTINCT(jp.id)) totalgameApplied,
            ja.application_assign_to_rp_status,
            1 AS rpAppliedSource,
            rja.create_date AS applied_on
        FROM
            (`refer_gameapplied` AS rja)
        JOIN `games_post` AS jp ON `jp`.`id` = `rja`.`game_id`
        JOIN `user_socialconnections` AS usc ON `rja`.`addressbook_id` = `usc`.`id`
        LEFT JOIN `user_user` AS usr ON `usr`.`email` = `rja`.`email`
        LEFT JOIN `user_member` AS mem ON `mem`.`user_id` = `usr`.`id`
        LEFT JOIN `game_applied` AS ja ON `ja`.`id` = `rja`.`applied_id`
        WHERE
            `rja`.`referby_id` = '2389'
        GROUP BY
            `rja`.`email`           
    )
    UNION ALL
        (
            SELECT
                ja.previous_status,
                ja.rejected_status,
                ja.rejection_reason_text,
                ja.rejection_reason,
                jr.id AS rjaId,
                jrtm. STATUS AS refer_applied_status,
                jp.title,
                jp.user_user_id AS playerId,
                jp.id AS gameId,
                jp.posted_on AS gamePostDate,
                jp.game_referal_amount,
                jp.country,
                jp.country_name,
                jp.state,
                jp.location,
                jp.state_abb,
                jp.game_type,
                ja.id AS appliedId,
                IFNULL(ja. STATUS, '') AS appliedStatus,
                IFNULL(ja.admin_review, '') AS admin_review,
                ja.is_req_referal_check,
                usr.id AS memberId,
                jrtm.referto_email AS refappliedEmail,
                jr.game_id,
                jrtm.id,
                mem.state_abb AS memStateAbb,
                mem.state AS memState,
                mem.zipcode AS memZipcode,
                mem.city AS memCity,
                mem.country_name AS memCountryNme,
                mem.country_code AS memCountry,
                usc. NAME AS appliedMemberName,
                usc.first_name,
                IFNULL(
                    mem.primary_contact,
                    usc.phone_number
                ) AS primary_contact,
                usc.last_name,
                usc.profileimage_path AS addressbookImage,
                usr.profile_image AS userImage,
                usr.last_login,
                mem.user_experience_year,
                mem.user_experience_month,
                mem.current_designation,
                mem.current_player,
                jrtm.refer_on AS appliedDate,
                jrtm.referto_addressbookid,
                IFNULL(ja.joining_date, '') AS joiningdate,
                jp. STATUS AS gameStatus,
                jp.games_referal_amount_type AS gameReferalAmountType,
                jp.game_freeze_status AS gameFreezeStatus,
                jp.game_freeze_message AS gameFreezeMsg,
                ja.app_assign_back_to_rp_count,
                ja.applied_source,
                MAX(jrtm.id) AS max_id,
                GROUP_CONCAT(
                    jp.title
                    ORDER BY
                        jr.refer_on DESC
                ) AS gamesApplied,
                GROUP_CONCAT(DISTINCT(jp.id)) AS gamesAppliedId,
                COUNT(DISTINCT(jp.id)) totalgameApplied,
                ja.application_assign_to_rp_status,
                2 AS rpAppliedSource,
                jrtm.refer_on AS applied_on
            FROM
                (`game_refer` AS jr)
            JOIN `game_refer_to_member` AS jrtm ON `jrtm`.`rid` = `jr`.`id`
            JOIN `games_post` AS jp ON `jp`.`id` = `jr`.`game_id`
            JOIN `user_socialconnections` AS usc ON `jrtm`.`referto_addressbookid` = `usc`.`id`
            LEFT JOIN `user_user` AS usr ON `usr`.`email` = `jrtm`.`referto_email`
            LEFT JOIN `user_member` AS mem ON `mem`.`user_id` = `usr`.`id`
            LEFT JOIN `game_applied` AS ja ON `ja`.`referred_by` = `jrtm`.`id`
            WHERE
                `jrtm`.`status` = '1'
            AND `jr`.`referby_user_id` = '2389'
            AND `jrtm`.`refer_source` NOT IN ('4')
            GROUP BY
                `jrtm`.`referto_email`
        )
) a
                GROUP BY
a.appliedEmail
                ORDER BY
a.gamesAppliedId DESC

最佳答案

这听起来像是一个“groupwise-max”问题。我添加了一个您应该研究的标签。

至少去掉与问题无关的列。

尝试折腾除 jrtm 和 jr 之外的表,看看性能问题是否仍然存在。 (我认为LEFT JOIN可能是转移注意力。)

尝试使用 UNION 的一部分,然后使用另一部分。这可以确定两者中哪一个负担更大。

要添加的一些索引:

rja:   (referby_id, create_date)
jrtm:  (status, referto_email)
jrtm:  (rid, status, referto_email)
jr:    (referby_user_id, refer_on)

DISTINCT 不是函数。不要在 DISTINCT(jp.id) 中使用父项。

关于MySQL 按顺序查找每组最近/最大记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49534239/

相关文章:

php - UTC 日期时间转换

mysql - 错误率: Condition Always False - Why?

mysql - 这里的加入似乎没有必要

mysql - 为什么限制 0,1 比限制 0、17 慢

mysql - 如何明智地获得第二高薪部门?

mysql - 如何选择具有唯一元素的对的最大子集?

php - SQL 中每组有 N 个项目 || SQL子查询限制

mysql - 执行 "global"GROUP BY 存储为 `field1` , `field2` 的字段的最佳方法

MYSQL Join - 父子表join,只获取子表的最新记录

mysql - 获得每家商店销量最高的产品 - 不断获得错误的产品但数量正确