0

我有一个rel包含字段id refid cellid cat和一些工作 PHP 代码的表来计算每个字段的行数,cellid并将其作为数组返回以供以后使用。

<?php
// connect to database
require($DOCUMENT_ROOT . "connect.php");
// count the number of relationships for each cell id
  $cell_array = array();
  if ($result = mysqli_query($link, "SELECT cellid, COUNT(*) totalcount, cat FROM rel GROUP BY cellid")) {
    if (mysqli_num_rows($result)) {
      while ($row = mysqli_fetch_assoc($result)) {
        $cell_array[$row["cellid"]] = $row['totalcount'];
      }
    }
  }
?>

我现在想添加一个附加函数,计算每个函数的模式(最常见的值)cat并将cellid该值包含在数组中。如果有多个模式或没有模式,则返回 9(cat只能有 1 到 8 的值)。

我一直在阅读如何找到模式,常见的解决方案如下所示:

SELECT COUNT(*) frequency, cat, cellid
FROM rel
GROUP BY cat
ORDER BY COUNT(*) DESC
LIMIT 1

但这并没有返回cat每个最常见的,cellid只是最常见cat的。

我一直在使用子查询

SELECT cellid, cat, COUNT( * ) 
FROM  `rel` 
GROUP BY cellid, cat

它为每个组合生成一行cellid cat,但我不确定如何使用它来查找每个组合的条目总数以及每个组合cellid最常见的条目数catcellid

编辑

我已经取得了一些进一步的进展,我现在有一个工作查询来查找cat每个模式的模式cellid

SELECT cellid, cat
FROM rel t
GROUP BY cellid, cat
HAVING cat = ( 
SELECT cat
FROM rel
WHERE cellid = t.cellid
GROUP BY cat
ORDER BY COUNT( * ) DESC , cat
LIMIT 1 )

但是我仍然不确定如何组合这两个查询,因为一个查询的输出不能用于另一个查询。

4

1 回答 1

0

您可以通过将它们连接在一起来组合它们:

select cell.*, mode.cat as modecat
from (SELECT cellid, COUNT(*) totalcount
      FROM rel
      GROUP BY cellid
     ) cell join
     (SELECT cellid, cat
      FROM rel t
      GROUP BY cellid, cat
      HAVING cat = (SELECT cat
                    FROM rel
                    WHERE cellid = t.cellid
                    GROUP BY cat
                    ORDER BY COUNT( * ) DESC , cat
                    LIMIT 1
                  )
     ) mode
     on cell.cellid = mode.cnt

这不处理多个值的情况。如果您只想要一个任意值,我会选择:

select cell.*,
       (select cat
        from rel
        where cell.cellid = rel.cellid
        group by cellid, cat
        order by COUNT(*) desc
        limit 1
       ) as mode
from (SELECT cellid, COUNT(*) totalcount
      FROM rel
      GROUP BY cellid
     ) cell

识别 muliples 有点棘手。它需要在子查询中进行额外的聚合:

select cell.*,
       (select (case when min(cat) = max(cat) then min(cat) else 'MULTIPLE' end) as mode
        from (select cat, COUNT(*) as cnt
              from rel
              where cell.cellid = rel.cellid
              group by cellid, cat
             ) t
        group by cnt
        order by cnt desc
        limit 1
       ) mode
from (SELECT cellid, COUNT(*) totalcount
      FROM rel
      GROUP BY cellid
     ) cell
于 2012-10-24T19:33:23.027 回答