PHP MySQL 显示分组和标记重复项


PHP MySQL Show Grouped & Tag Duplicates

我有一个数据库,它有一个表,如下所示:

ID | FNAME | LNAME | DATE

有些行有重复的名字/姓氏,我需要能够检测到它们是重复的,当我将它们显示为列表时,显示数字。

我需要使输出如下:

First Name (FNAME) / Last Name (LNAME) | Duplicate? Dupe #

我的数据库连接如下所示:

$query = "SELECT 
            FNAME,
            LNAME, 
            COUNT(LNAME) AS TOTAL
          FROM user_list
          GROUP BY LNAME";

PHP 代码如下所示:

while($row = mysql_fetch_array($res)){
 echo $row['FNAME'] . " / " . $row['FNAME']. " | ". $row['TOTAL'];
 echo "<br />";
}

我似乎无法对所有内容进行分组并显示所有查询以及计数/显示总计。

所以我需要它看起来像:

汤姆/史密斯 | 1迈克/罗布斯 |1汤姆/史密斯 |阿拉伯数字

所以。。。如果存在 2+ 个条目,则显示每个条目及其在数据库中出现的条目。

如果需要输出如下所示:

TOM / SMITH | 1
MIKE / ROBS | 1
TOM / SMITH | 2

那么这确实是非常复杂的。 但我认为这是可以做到的,即使在一个 SQL 语句中尝试这一切。

假设您希望它们按名称以外的其他顺序排列(所有 TOM SMITH 一起出现),那么您可能需要添加一个唯一的 ID 字段,我假设您也想按此 ID 字段排序。 然后你可以有这样的东西:

SET @name_count := 0, @prev_name := '';
SELECT FNAME, LNAME, namecount FROM user_list AS t1
INNER JOIN (
    SELECT
        ID,
        (@name_count := IF(@prev_name = CONCAT(FNAME, ' ', LNAME), @name_count+1, 1)) AS namecount,
        (@prev_name := CONCAT(FNAME, ' ', LNAME)) AS prevname
    FROM (SELECT * FROM user_list ORDER BY FNAME ASC, LNAME ASC) AS tmp
    ) AS t2 ON t1.ID = t2.ID
ORDER BY t1.ID ASC;

笔记:

  1. @name_count和@prev_name的 SQL 变量确实取决于 select 语句的顺序,因此内部的 ORDER BY。
  2. 内部子查询按名称排序,并为每个名称分配增量排名,当遇到新名称时从 1 开始。
  3. 请注意,(@prev_name := ...)必须列在 (@name_count := IF(@prev_name = ..., ..., ...) 之后,否则它会先分配prev_name,然后再为每行分配name_count,从而导致@prev_name始终等于当前名称。
  4. 内部 SQL 为每个
  5. 名称实例分配"rank",外部 SQL 将按原始顺序显示它们。
  6. FROM (SELECT * FROM user_list ORDER BY FNAME ASC, LNAME ASC) AS tmp部分不必是子查询。 它可以是FROM user_list ORDER BY FNAME ASC, LNAME ASC. 但我注意到在某些情况下,根据您使用ORDER BY,特别是如果有多个字段,可能会导致一些意外的排序。 这就是为什么我将该表作为另一个子查询放置的原因 - 因此它可以首先正确地进行名称排序,然后进行排名。
  7. 您可能需要在 PHP 中将其作为两个单独的查询运行。一个查询是SET @name_count := 0, @prev_name := '';,另一个查询是字符串的其余部分。如果您尝试在 PHP 中将整个字符串作为一个查询,则在大多数情况下,它将尝试将其视为一个查询。在phpMyAdmin或mysql控制台中,它会将其识别为两个单独的查询。

另一种方法是在PHP而不是MySQL中进行计数,当您遍历输出时,您保留该名称的最后一个计数数组,并在名称出现时增加计数。