【问题标题】:Using one sub query result multiple times in the same mysql query在同一个mysql查询中多次使用一个子查询结果
【发布时间】:2017-03-30 13:38:05
【问题描述】:

如何在同一个查询中多次使用一个子查询的结果集

SELECT
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = '1'
    ) be ON joa.referred_by = be.id
) AS applicationcount,
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = '1'
    ) bf ON joa.referred_by = bf.id
    AND joa.admin_review = '3'
    AND joa.rejection_reason = 'Admin rejected your game'
) AS admin_reject,
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = '1'
    ) bg ON joa.referred_by = bg.id
    AND joa. STATUS = '5'
    AND joa.admin_review = '2'
) AS employer_reject,
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = '1'
    ) bd ON joa.referred_by = bd.id
    AND joa.admin_review = '1'
) AS admin_review,
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = '1'
    ) bc ON joa.referred_by = bc.id
    AND joa.admin_review = '5'
) AS accountmanager_review,
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = '1'
    ) ba ON joa.referred_by = ba.id
    AND joa.admin_review = '6'
) AS rp_review,
(
    SELECT
        COUNT(joa.id)
    FROM
        game_applied joa
    INNER JOIN (
        SELECT
            jrmm.id
        FROM
            game_refer_to_member jrmm
        JOIN game_refer jrr ON jrr.id = jrmm.rid
        AND jrr.referby_user_id = 2551
        AND jrmm. STATUS = 1
    ) bh ON joa.referred_by = bh.id
    AND joa.admin_review = '2'
    AND (
        joa. STATUS = '' || joa. STATUS = 1 || joa. STATUS = 2 || joa.    STATUS = 3 || joa. STATUS = 4
    )
) AS other_status 
  FROM
game_applied ja
JOIN user_user u ON u.id = ja.applied_recruiter_id
INNER JOIN (
SELECT
    jrmm.id
FROM
    game_refer_to_member jrmm
    JOIN game_refer jrr ON jrr.id = jrmm.rid
AND jrr.referby_user_id = 2551
AND jrmm. STATUS = '1'
) bn ON ja.referred_by = bn.id
GROUP BY
applicationcount

如何在同一个查询中多次使用一个子查询的结果集

子查询在这个查询中使用了多次到一次使用

(
SELECT
    jrmm.id
FROM
    game_refer_to_member jrmm
JOIN game_refer jrr ON jrr.id = jrmm.rid
AND jrr.referby_user_id = 2551
AND jrmm. STATUS = '1'
  ) bn ON ja.referred_by = bn.id

【问题讨论】:

    标签: mysql sql select join subquery


    【解决方案1】:

    试试这个:

    SELECT COUNT(joa.id) AS applicationcount, 
             SUM(joa.admin_review = '3' AND joa.rejection_reason = 'Admin Rejected your resume') AS admin_reject, 
             SUM(joa.STATUS = '5' AND joa.admin_review = '2') AS employer_reject, 
             SUM(joa.admin_review = '1') AS admin_review, 
             SUM(joa.admin_review = '5') AS accountmanager_review, 
             SUM(joa.admin_review = '6') AS rp_review, 
             SUM(joa.admin_review = '2' AND joa.STATUS != '5') AS other_status, 
    FROM game_refer_to_member jrmm 
    INNER JOIN game_refer jrr ON jrr.id = jrmm.rid AND jrr.referby_user_id = 2551 
    INNER JOIN game_applied joa ON jrmm.id  = joa.referred_by  
    INNER JOIN user_user u ON u.id = joa.applied_recruiter_id
    WHERE jrmm.STATUS = '1' 
    

    【讨论】:

      【解决方案2】:

      好的...我将尝试首先弄清楚查询的作用。我将替换以下所有实例:

      SELECT
          COUNT(joa.id)
      FROM
          game_applied joa
      INNER JOIN (
          SELECT
              jrmm.id
          FROM
              game_refer_to_member jrmm
          JOIN game_refer jrr ON jrr.id = jrmm.rid
          AND jrr.referby_user_id = 2551
          AND jrmm. STATUS = '1'
      

      用这句话:

      ( SELECT count(*) FROM joa JOIN (subselect))
      

      ...为了清楚起见。

      我还删除了 GROUP BY,因为它没有用和/或被误导,除非你能解释为什么它在那里。

      我假设 ja.applied_recruiter_id 是一个外键,这意味着......

      JOIN user_user u ON u.id = ja.applied_recruiter_id
      

      ...总是返回一行。由于实际未选择 user_user 中的列,因此可以删除此连接。现在,这部分:

          INNER JOIN (
              SELECT
                  jrmm.id
              FROM
                  game_refer_to_member jrmm
                  JOIN game_refer jrr ON jrr.id = jrmm.rid
              AND jrr.referby_user_id = 2551
              AND jrmm. STATUS = '1'
          ) bn ON ja.referred_by = bn.id
      

      ...目前尚不清楚这是做什么的。由于子选择与先前查询中的子选择相同,因此它不太可能过滤整个查询返回的行。我想说它的唯一效果是无用地重复行,这解释了为什么有一个 GROUP BY... 所以,它消失了。

      我们得到:

      SELECT
      ( SELECT count(*) FROM joa JOIN (subselect)) be ON joa.referred_by = be.id ) AS applicationcount,
      ( SELECT count(*) FROM joa JOIN (subselect)) bf ON joa.referred_by = bf.id
          AND joa.admin_review = '3'
          AND joa.rejection_reason = 'Admin rejected your game'
      ) AS admin_reject,
      ( SELECT count(*) FROM joa JOIN (subselect)) bg ON joa.referred_by = bg.id
          AND joa. STATUS = '5'
          AND joa.admin_review = '2'
      ) AS employer_reject,
      ( SELECT count(*) FROM joa JOIN (subselect)) bd ON joa.referred_by = bd.id
          AND joa.admin_review = '1'
      ) AS admin_review,
      ( SELECT count(*) FROM joa JOIN (subselect)) bc ON joa.referred_by = bc.id
          AND joa.admin_review = '5'
      ) AS accountmanager_review,
      ( SELECT count(*) FROM joa JOIN (subselect)) ba ON joa.referred_by = ba.id
          AND joa.admin_review = '6'
      ) AS rp_review,
      ( SELECT count(*) FROM joa JOIN (subselect)) bh ON joa.referred_by = bh.id
          AND joa.admin_review = '2'
          AND (joa. STATUS = '' || joa. STATUS = 1 || joa. STATUS = 2 || joa.    STATUS = 3 || joa. STATUS = 4)
      ) AS other_status 
        FROM
      game_applied ja
      

      ...并且,使用与 Sarhash 相同的逻辑,我们将其简化为:

      SELECT COUNT(joa.id) AS applicationcount, 
           SUM(joa.admin_review = '3' AND joa.rejection_reason = 'Admin Rejected your resume') AS admin_reject, 
           SUM(joa.STATUS = '5' AND joa.admin_review = '2') AS employer_reject, 
           SUM(joa.admin_review = '1') AS admin_review, 
           SUM(joa.admin_review = '5') AS accountmanager_review, 
           SUM(joa.admin_review = '6') AS rp_review, 
           SUM(joa.admin_review = '2' AND joa.STATUS != '5') AS other_status, 
      FROM game_refer_to_member jrmm 
      INNER JOIN game_refer jrr ON jrr.id = jrmm.rid 
      INNER JOIN game_applied joa ON jrmm.id  = joa.referred_by  
      WHERE jrmm.STATUS = '1' AND jrr.referby_user_id = 2551
      

      (这是相同的,减去对 USER 的无用连接和在 WHERE 中的清理,谢谢 Sarhash,你得到了所有的功劳)。

      【讨论】:

      • 谢谢@peufeu
      【解决方案3】:

      我使用CREATE TEMPORARY TABLE 找到了一个可行的解决方案。我建议在同一个会话中背靠背运行两个查询。首先,从要多次引用的子查询中创建一些临时表:

      CREATE
      TEMPORARY TABLE temp_table1
        (SELECT COUNT(joa.id)
         FROM game_applied);
      
      CREATE
      TEMPORARY TABLE new_table
        (SELECT jrmm.id
         FROM game_refer_to_member jrmm
         JOIN game_refer jrr ON jrr.id = jrmm.rid
         AND jrr.referby_user_id = 2551
         AND jrmm. STATUS = '1');
      

      使用这些临时表名对原始查询运行简单的查找和替换后,新查询将如下所示:

      SELECT
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN temp_table2 be ON joa.referred_by = be.id) AS applicationcount,
      
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN temp_table2 bf ON joa.referred_by = bf.id
         AND joa.admin_review = '3'
         AND joa.rejection_reason = 'Admin rejected your game') AS admin_reject,
      
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN temp_table2 bg ON joa.referred_by = bg.id
         AND joa. STATUS = '5'
         AND joa.admin_review = '2') AS employer_reject,
      
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN temp_table2 bd ON joa.referred_by = bd.id
         AND joa.admin_review = '1') AS admin_review,
      
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN temp_table2 bc ON joa.referred_by = bc.id
         AND joa.admin_review = '5') AS accountmanager_review,
      
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN temp_table2 ba ON joa.referred_by = ba.id
         AND joa.admin_review = '6') AS rp_review,
      
        (SELECT *
         FROM temp_table1 joa
         INNER JOIN
           (SELECT jrmm.id
            FROM game_refer_to_member jrmm
            JOIN game_refer jrr ON jrr.id = jrmm.rid
            AND jrr.referby_user_id = 2551
            AND jrmm. STATUS = 1) bh ON joa.referred_by = bh.id
         AND joa.admin_review = '2'
         AND (joa. STATUS = '' || joa. STATUS = 1 || joa. STATUS = 2 || joa. STATUS = 3 || joa. STATUS = 4)) AS other_status
      FROM game_applied ja
      JOIN user_user u ON u.id = ja.applied_recruiter_id
      INNER JOIN temp_table2 bn ON ja.referred_by = bn.id
      GROUP BY applicationcount
      

      我不保证此查询没有错误,因为我没有您的数据库,因此无法轻松测试它,但这至少概述了我认为应该改进的体面策略性能,并且至少使查询大小减少了一半。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-29
        • 1970-01-01
        • 2013-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多