【问题标题】:Php & Mysql, filter out subqueries from PHP-for loop into MySQL statementPHP & Mysql,过滤掉 PHP-for 循环中的子查询到 MySQL 语句中
【发布时间】:2011-12-08 10:59:01
【问题描述】:

我必须修改一个连接到极其混乱的数据库设计的 PHP 脚本。 解释这个问题的最好方法是发布代码,我将在其中描述通过代码块内的 cmets 发生的事情。加上一个简短的介绍:

短篇小说:
1.) 有一个“mainQuery”,在显示其数据的 for 循环内有 3 个嵌套子查询。
2.) 所有三个子查询都需要 main_table_ID 来计算每个 fetched_row 的出现次数。

我想要什么:
1.) 一个经过优化的 mainQuery,它单独计算 3 个 id 的出现次数。
2.) 因此,for 循环内根本没有子查询。

我通过优化 mainQuery 已经取得的成果:
1.) 我可以一次过滤一个子查询,请参阅语句:

SELECT
       main_table.id_col,
       count(table_1.a_col) AS count_1,
       main_table.a_col,
       main_table.b_col,
       main_table.c_col,
       main_table.d_col,
       main_table.e_col

FROM   main_table
LEFT JOIN
       table_1
ON
       table_1.a_col = main_table.id_col
GROUP BY
       main_table.id_col

但是当我在 for 循环中为其他嵌套语句之一添加另一个 LEFT JOIN 时,该语句将所有内容相加,并且 count_1 到 count_3 看起来相同。

现在是包含子查询和 for 循环的代码块:

<?php
$mainQuery = "SELECT 
                          main_table.id_col, 
                          main_table.a_Col, 
                          main_table.b_Col, 
                          main_table.c_col, 
                          main_table.d_col, 
                          main_table.e_col 
                   FROM 
                          main_table";

$mainQueryResult = mysql_query($mainQuery);
$mainQueryRows = mysql_num_rows($mainQueryResult);

for($j = 0 ; $j < $mainQueryRows ; ++$j){
    //mainQuery data
    $mainQueryRow = mysql_fetch_row($mainQueryResult);
    $main_table_ID = $mainQueryRow[0];

    //first subquery, can be filtered out one at a time 
    //using introductory-statement
    $count_1_subQuery = "SELECT * FROM table_1 
                         WHERE table_1.id_col = '$main_table_ID'";
    //first subquery-count of rows with matching id
    $count_1 = mysql_num_rows(mysql_query($count_1_SubQuery, $connection));

    //second subquery
    $count_2_subquery = "SELECT * FROM table_2 
             WHERE table_2.id_col = '$main_table_ID'";
    //second subquery-count of rows with matching id
    $count_2 = mysql_num_rows(mysql_query($count_2_subQuery, $connection));

    //third subquery
    $count_3_subquery = "SELECT * FROM table_3 
             WHERE table_3.id_col = '$main_table_ID'";
    //third subquery-count of rows with matching id
    $count_3 = mysql_num_rows(mysql_query($count_3_subQuery, $connection));

    //Fill Table with count_1 to count_3 
        //and main_table.a_col to main_table.e_col
    //no problems here
}
?>

我希望我能足够清楚地解释这个问题,我也希望你们中的一个可以帮助我,如果他/她可以分配时间来解决这样的问题。

【问题讨论】:

    标签: php mysql subquery


    【解决方案1】:

    首先GROUP BY 在子查询中,然后JOIN 到主表:

    SELECT  
          m  . id_col
        , g1 . count_1  
        , g2 . count_2  
        , g3 . count_3  
        , m  . a_col  
        , m  . b_col  
        , m  . c_col  
        , m  . d_col  
        , m  . e_col      
    FROM 
            main_table AS m
        LEFT JOIN 
            ( SELECT id_col
                  , COUNT(*) AS count_1  
              FROM table_1  
              GROUP BY id_col 
            ) AS g1
          ON g1.id_col = m.id_col
        LEFT JOIN 
            ( SELECT id_col
                   , COUNT(*) AS count_2  
              FROM table_2 
              GROUP BY id_col 
            ) AS g2
          ON g2.id_col = m.id_col
        LEFT JOIN 
            ( SELECT id_col
                   , COUNT(*) AS count_3  
              FROM table_3  
              GROUP BY id_col 
            ) AS g3
          ON g3.id_col = m.id_col
    

    【讨论】:

    • 行动:“以上述方式修改”。结果:“按预期工作”。谢谢
    【解决方案2】:
    SELECT  
      main_table.id_col,  
      count(DISTINCT t1.id_col) AS count_1,  
      count(DISTINCT t2.id_col) AS count_2,  
      count(DISTINCT t3.id_col) AS count_3,  
      main_table.a_col,  
      main_table.b_col,  
      main_table.c_col,  
      main_table.d_col,  
      main_table.e_col      
    FROM  main_table m
    LEFT JOIN table_1 t1 ON (t1.id_col = m.id_col)
    LEFT JOIN table_2 t2 ON (t2.id_col = m.id_col)
    LEFT JOIN table_3 t3 ON (t3.id_col = m.id_col)
    GROUP BY m.id_col  
    

    【讨论】:

    • 结果:计数不正确,count_1 还汇总了 count_2 和 count_3 的连接完成的命中数。
    • 在计数中添加distinct
    • 操作:“添加不同”。结果:所有计数不超过 count = "1"。不工作。仍在寻找解决方案。
    • @kiltek:您可以尝试将:count(DISTINCT t1.id_col) 更改为count(DISTINCT t1.PK),其中PKtable_1 的主键。
    猜你喜欢
    • 2011-03-21
    • 2014-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-15
    • 2012-05-31
    • 1970-01-01
    相关资源
    最近更新 更多