COUNT / GROUP BY查询无效

时间:2015-09-22 23:43:28

标签: php mysql

我想显示某些联合表中的重复值列表。我的目标是显示两列,第一列列出字段URL中的重复值,第二列显示每个值的实例数,如下所示......

非洲(2)

usa(4)

我无法弄清楚我的查询有什么问题。当我在MySQL中试用它> SQL,它给了我一个“空结果集”。我仔细检查了表格,他们都有一个名为URL的字段。

更新:我错误地在每个表上分组网址;特定表中没有重复值。我试图通过将GROUP BY子句移动到查询的末尾来修复它。

但我仍然做错了什么。当我将查询粘贴到SQL中时,它应该显示多个URL,每个URL包含两个实例。相反,它显示“earth 471”。在我的网页上,我看到错误致命错误:[]操作符不支持字符串

此外,在代码的最后,如何显示第二列?

$stm = $pdo->prepare("SELECT *
FROM (
 SELECT URL, COUNT(*) c FROM gw_geog_political
 UNION ALL 
 SELECT URL, COUNT(*) c FROM gw_geog
) AS Combined
GROUP BY URL HAVING c > 1");
 $stm->execute(array(
));

while ($row = $stm->fetch())
{
 $URL[] = $row['URL'];
}

echo join( $URL, '' );

1 个答案:

答案 0 :(得分:1)

  1.   

    当我在MySQL中尝试时> SQL,它给了我一个"空结果集。"我仔细检查了表格,他们都有一个名为URL的字段。

    如果其中一个(或两个)有一个名为URL的列,您会看到Error 1054。空结果集表示查询运行没有问题,但没有产生任何结果。

  2.   

    我错误地在每个表上分组URL;特定表中没有重复值。我试图通过将GROUP BY子句移动到查询的末尾来修复它。

         

    但我仍然做错了什么。当我将查询粘贴到SQL中时,它应该显示多个URL,每个URL包含两个实例。相反,它显示" earth 471。"

    通过将GROUP BY移动到外部查询,您可以使用COUNT()聚合函数但没有自己的GROUP BY子句的内部查询。但是,如GROUP BY (Aggregate) Functions所述:

      

    如果在不包含GROUP BY子句的语句中使用组函数,则相当于对所有行进行分组。

    因此,UNION的每个成分都会产生完全一个记录(包含不确定URL和任何{{1}的记录总数的计数},在基础表中。)

    外部查询中的分组操作导致只有一条记录的结果集意味着在每种情况下选择的URL的不确定值恰好相同(在这种情况下{{1}的值不确定地从内部查询的两个基础结果中选择),或者两个表中的一个是空的。

    要在尝试时在外部查询中执行聚合,您还需要在那里移动URL函数:

    c

    但是,由于"特定表中没有重复的值",您真正想要获得的是两个表中出现的URL列表({{1永远是两个)。这可以通过内连接更直接地实现:

    COUNT()

    如果"在特定表中重复值"将来可能存在,你可以简单地将SELECT URL, COUNT(*) c FROM ( SELECT URL FROM gw_geog_political UNION ALL SELECT URL FROM gw_geog ) AS Combined GROUP BY URL HAVING c > 1 添加到上面的查询中,以便从结果集中删除它们 - 虽然要获得实际的计数需要更多的工作:

    COUNT()

    但是,在这种情况下,您的原始方法(在内部查询中分组)可能会更有效 - 您只需要在外部查询中再次组合,总结内部计数:

    SELECT URL FROM gw_geog_political JOIN gw_geog USING (URL)
    
  3.   

    在我的网页上,我看到错误致命错误:字符串不支持[]运算符

    这可能是因为在您显示的代码段之前的某个时间段为您的DISTINCT变量分配了非空字符串。因此,在循环中使用SELECT URL, COUNT(DISTINCT gp.id) + COUNT(DISTINCT g.id) AS c FROM gw_geog_political gp JOIN gw_geog g USING (URL) GROUP BY URL 在其中构造结果值数组的尝试将失败并显示您看到的错误。在进入循环之前,您应该将所需的变量初始化为空数组,以确保:

    SELECT   URL, SUM(c) c
    FROM     (
               SELECT URL, COUNT(*) c FROM gw_geog_political GROUP BY URL
             UNION ALL 
               SELECT URL, COUNT(*) c FROM gw_geog GROUP BY URL
             ) AS Combined
    GROUP BY URL
    HAVING   c > 1
    

    请注意,使用PDO fetchAll()方法可以获得相同的结果:

    $URL

    然而,将整个结果集加载到PHP数组中通常是一个坏主意,因为这可能会不必要地占用大量内存(无论如何,您只需要第二次循环,而不是结果数组,以便对其进行操作)。如果您在获取结果时能够执行最终操作(在这种情况下输出),那么这通常会更有效:

    $URL[] = ...
  4.   

    此外,在代码的最后,如何显示第二列?

    如上所述,每种情况下的计数必然是 2 。但是,如果要使用结果集中的其他列,则可以相应地修改循环:

    $URL = array();
    while ($row = $stm->fetch())
    {
     $URL[] = $row['URL'];
    }