Mysql 循环浏览表格的每条记录,并对所有其他记录执行计算

Mysql 循环浏览表格的每条记录,并对所有其他记录执行计算,mysql,sql,Mysql,Sql,我想在我的表工作 无最高评级的计算方法为: 对于每一行,从该记录的ANNDATS\u CONVERTED中获取上一年内的所有其他行,并具有与该记录相同的ESTIMID 从中找到最低的IRECD值 然后,计算相同的分析员拥有与计算出的最低IRECCD匹配的IRECCD的次数 注意:这应忽略正在计算的当前行(以便找到行id 1的值,在计算中不要使用此行),并且应完全忽略ANALYST为空的任何记录 表工作: | ID | ANALYST | ESTIMID | ANNDATS_

我想在我的表
工作

无最高评级的计算方法为:

  • 对于每一行,从该记录的
    ANNDATS\u CONVERTED
    中获取上一年内的所有其他行,并具有与该记录相同的
    ESTIMID
  • 从中找到最低的
    IRECD
  • 然后,计算相同的
    分析员
    拥有与计算出的最低
    IRECCD
    匹配的
    IRECCD的次数
注意:这应忽略正在计算的当前行(以便找到行id 1的值,在计算中不要使用此行),并且应完全忽略
ANALYST
为空的任何记录

工作

    | ID | ANALYST |   ESTIMID    | ANNDATS_CONVERTED |   IRECCD    | NO_TOP_RATING |
    ---------------------------------------------------------------------------------
    | 1  |  DAVE   | Brokerage000 |    1998-07-01     |     2       |               |
    | 2  |  DAVE   | Brokerage000 |    1998-06-28     |     2       |               |
    | 3  |  DAVE   | Brokerage000 |    1998-07-02     |     4       |               |
    | 4  |  DAVE   | Brokerage000 |    1998-07-04     |     3       |               |
    | 5  |  SAM    | Brokerage000 |    1998-06-14     |     1       |               |
    | 6  |  SAM    | Brokerage000 |    1998-06-28     |     4       |               |
    | 7  |         | Brokerage000 |    1998-06-28     |     1       |               |
    | 8  |  DAVE   | Brokerage111 |    1998-06-28     |     5       |               |
| ID | ANALYST |   ESTIMID    | ANNDATS_CONVERTED |   IRECCD    | NO_TOP_RATING |
---------------------------------------------------------------------------------
| 1  |  DAVE   | Brokerage000 |    1998-07-01     |     2       |       0       |
| 2  |  DAVE   | Brokerage000 |    1998-06-28     |     2       |       0       |
| 3  |  DAVE   | Brokerage000 |    1998-07-02     |     4       |       0       |
| 4  |  DAVE   | Brokerage000 |    1998-07-04     |     3       |       0       |
| 5  |  SAM    | Brokerage000 |    1998-06-14     |     1       |       0       |
| 6  |  SAM    | Brokerage000 |    1998-06-28     |     4       |       1       |
| 7  |         | Brokerage000 |    1998-06-28     |     1       |               |
| 8  |  DAVE   | Brokerage111 |    1998-06-28     |     5       |       0       |

因此-当计算
无最高评级时,记录#1:

  • 记录#1包括在计算中,因为我想从计算中省略它
  • 记录#7根本不包含在计算中,因为
    分析师
    为空
  • 记录#8包括在计算中,因为
    ESTIMID
    与记录#1不同

预期结果:

工作

    | ID | ANALYST |   ESTIMID    | ANNDATS_CONVERTED |   IRECCD    | NO_TOP_RATING |
    ---------------------------------------------------------------------------------
    | 1  |  DAVE   | Brokerage000 |    1998-07-01     |     2       |               |
    | 2  |  DAVE   | Brokerage000 |    1998-06-28     |     2       |               |
    | 3  |  DAVE   | Brokerage000 |    1998-07-02     |     4       |               |
    | 4  |  DAVE   | Brokerage000 |    1998-07-04     |     3       |               |
    | 5  |  SAM    | Brokerage000 |    1998-06-14     |     1       |               |
    | 6  |  SAM    | Brokerage000 |    1998-06-28     |     4       |               |
    | 7  |         | Brokerage000 |    1998-06-28     |     1       |               |
    | 8  |  DAVE   | Brokerage111 |    1998-06-28     |     5       |               |
| ID | ANALYST |   ESTIMID    | ANNDATS_CONVERTED |   IRECCD    | NO_TOP_RATING |
---------------------------------------------------------------------------------
| 1  |  DAVE   | Brokerage000 |    1998-07-01     |     2       |       0       |
| 2  |  DAVE   | Brokerage000 |    1998-06-28     |     2       |       0       |
| 3  |  DAVE   | Brokerage000 |    1998-07-02     |     4       |       0       |
| 4  |  DAVE   | Brokerage000 |    1998-07-04     |     3       |       0       |
| 5  |  SAM    | Brokerage000 |    1998-06-14     |     1       |       0       |
| 6  |  SAM    | Brokerage000 |    1998-06-28     |     4       |       1       |
| 7  |         | Brokerage000 |    1998-06-28     |     1       |               |
| 8  |  DAVE   | Brokerage111 |    1998-06-28     |     5       |       0       |

以下是我目前拥有的MySQL:

    UPDATE `working`

SET `working`.`NO_TOP_RATING` = 


(
    SELECT COUNT(`ID`) FROM  (SELECT `ID`,`IRECCD`,`ESTIMID` FROM `working`) AS BB 

    WHERE

    `IRECCD` =                                  


            (
                SELECT COUNT(`ID`) FROM  (SELECT `ID`,`IRECCD`,`ESTIMID`, `ANALYST` FROM `working`) AS ZZ 
                WHERE

                `IRECCD` =
                            -- this calculates the LOWEST number with same `ESTIMID`
                            (

                                SELECT MIN(`IRECCD`)
                                FROM (SELECT `ID`,`IRECCD`,`ANNDATS_CONVERTED`,`ESTIMID` FROM `working`) AS CC 

                                WHERE
                                `ANNDATS_CONVERTED` >= DATE_SUB(`ANNDATS_CONVERTED`,INTERVAL 1 YEAR)
                                AND
                                `working`.`ESTIMID` = BB.`ESTIMID`

                            )
                            -- END this calculates the LOWEST number with same `ESTIMID`

                AND
                `working`.`ANALYST` = ZZ.`ANALYST`
            )




)
WHERE `working`.`ANALYST` != ''


这是在PHP中工作的,循环遍历每个记录并评估每个记录的所有其他记录。这涉及到循环,在大型数据库上需要很长时间。我试图用MySQL获得同样的结果。

我采取了一些步骤来解决这个问题。我做的第一件事就是编写一个
JOIN
,它得到了我需要的所有行。我在几个条件下加入了表格:

  • 这场比赛的结果是一致的
  • id值不相同
  • 两个表中的analyst列均不为null
  • 一个表的anndats_转换值在另一个表的上一年内
为了进行测试,我从两个表中选择了id,以确保获得正确的配对:

SELECT w.id, wo.id
FROM working w
JOIN working wo 
    ON w.estimid = wo.estimid
    AND w.id != wo.id
    AND w.analyst IS NOT NULL
    AND wo.analyst IS NOT NULL
    AND wo.anndats_converted BETWEEN DATE_SUB(w.anndats_converted, INTERVAL 1 YEAR) AND w.anndats_converted
ORDER BY w.id;
| id | id |
+----+----+
| 1  | 2  |
| 1  | 5  |
| 1  | 6  |
| 2  | 5  |
| 2  | 6  |
一个简短的结果集显示了以下配对:

SELECT w.id, wo.id
FROM working w
JOIN working wo 
    ON w.estimid = wo.estimid
    AND w.id != wo.id
    AND w.analyst IS NOT NULL
    AND wo.analyst IS NOT NULL
    AND wo.anndats_converted BETWEEN DATE_SUB(w.anndats_converted, INTERVAL 1 YEAR) AND w.anndats_converted
ORDER BY w.id;
| id | id |
+----+----+
| 1  | 2  |
| 1  | 5  |
| 1  | 6  |
| 2  | 5  |
| 2  | 6  |
这似乎符合你的要求。对于id#1,第1行被排除在外(因为它正在计算中)。第3行和第4行不在正确的日期范围内,第7行为空,第8行为不同的估计值

然后,我使用聚合函数通过按第一个表分组来计算最小IRECD:

SELECT w.id, w.analyst, MIN(wo.ireccd) AS min_ireccd
FROM working w
JOIN working wo 
    ON w.estimid = wo.estimid
    AND w.id != wo.id
    AND w.analyst IS NOT NULL
    AND wo.analyst IS NOT NULL
    AND wo.anndats_converted BETWEEN DATE_SUB(w.anndats_converted, INTERVAL 1 YEAR) AND w.anndats_converted
GROUP BY w.id;
下一部分也很棘手,所以我将分两步进行解释。我将上面的查询与原始表连接起来,唯一的条件是分析列匹配。在某种程度上,这创造了一个笛卡尔积。查询如下所示:

SELECT *
FROM working w
LEFT JOIN(
    SELECT w.id, w.analyst, MIN(wo.ireccd) AS min_ireccd
    FROM working w
    LEFT JOIN working wo 
        ON w.estimid = wo.estimid
        AND w.id != wo.id
        AND w.analyst IS NOT NULL
        AND wo.analyst IS NOT NULL
        AND wo.anndats_converted BETWEEN DATE_SUB(w.anndats_converted, INTERVAL 1 YEAR) AND w.anndats_converted
    GROUP BY w.id) temp ON temp.analyst = w.analyst;
| id | analyst | ireccd | id | analyst | min_ireccd |
+----+---------+--------+----+---------+------------+
| 1  |  DAVE   |    2   | 8  |  DAVE   |      null  |
| 1  |  DAVE   |    2   | 4  |  DAVE   |      1     |
| 1  |  DAVE   |    2   | 1  |  DAVE   |      1     |
| 1  |  DAVE   |    2   | 2  |  DAVE   |      1     |
| 1  |  DAVE   |    2   | 3  |  DAVE   |      1     |
我看到了每个人所有可能的配对,如下所示:

SELECT *
FROM working w
LEFT JOIN(
    SELECT w.id, w.analyst, MIN(wo.ireccd) AS min_ireccd
    FROM working w
    LEFT JOIN working wo 
        ON w.estimid = wo.estimid
        AND w.id != wo.id
        AND w.analyst IS NOT NULL
        AND wo.analyst IS NOT NULL
        AND wo.anndats_converted BETWEEN DATE_SUB(w.anndats_converted, INTERVAL 1 YEAR) AND w.anndats_converted
    GROUP BY w.id) temp ON temp.analyst = w.analyst;
| id | analyst | ireccd | id | analyst | min_ireccd |
+----+---------+--------+----+---------+------------+
| 1  |  DAVE   |    2   | 8  |  DAVE   |      null  |
| 1  |  DAVE   |    2   | 4  |  DAVE   |      1     |
| 1  |  DAVE   |    2   | 1  |  DAVE   |      1     |
| 1  |  DAVE   |    2   | 2  |  DAVE   |      1     |
| 1  |  DAVE   |    2   | 3  |  DAVE   |      1     |
请注意,将第一个
DAVE
与表中所有其他
DAVE
行进行比较另请注意我更改了上面的内部查询以包含外部联接,以便考虑所有行。如果没有要计算的内容,
min\u ireccd
将为空

我做的最后一件事是使用该结果集,并计算IRECD与min_IRECD匹配的次数。我按id分组,因此在上面的示例集中,它从不匹配,因此计数为0。这是最后一个查询。它将null值(第7行)保留为null,因为这是您预期的结果:

SELECT w.*, SUM(w.ireccd = temp.min_ireccd) AS NO_TOP_RATING
FROM working w
LEFT JOIN(
    SELECT w.id, w.analyst, MIN(wo.ireccd) AS min_ireccd
    FROM working w
    LEFT JOIN working wo 
        ON w.estimid = wo.estimid
        AND w.id != wo.id
        AND w.analyst IS NOT NULL
        AND wo.analyst IS NOT NULL
        AND wo.anndats_converted BETWEEN DATE_SUB(w.anndats_converted, INTERVAL 1 YEAR) AND w.anndats_converted
    GROUP BY w.id) temp ON temp.analyst = w.analyst
GROUP BY w.id;
以下是我得到的结果:

您能否编辑您的问题,以包含您共享的样本数据的预期结果?仍然存在一些混淆。例如,您希望行位于日期后一年内还是日期前一年内?因此,在计算第#1行的值时,是否应包括第#2行,因为它发生在第#1行之前?谢谢@McAdam331。符合条件的年份应为转换后的>=-1年。因此,一年前,直到ANNDATS\u转换为
。是-第2行将被包括在内,因为它在等于或大于1年前的范围内。是@McAdam331我将编辑问题以显示预期结果。谢谢你的帮助。你好,谢谢。我有一个问题的想法,但我想确保答案是正确的。谢谢@McAdam331您的回答。我一定会把这件事仔细研究一遍。我真的很感谢您的时间:)@kreevp有什么进展吗?当我看到您的结果表显示“1”作为记录(5),而不是记录(6)时,我有点不知所措,因为在我给出的示例中应该是这样的。