计算PHP,MySqli的可能性

时间:2014-10-09 14:45:58

标签: php mysql

我有一张6个数字的表格。

1   5   8   14  35  45  Mon
13  26  30  31  43  49  Sat
1   4   13  19  34  39  Wed
2   20  21  24  25  43  Mon
1   6   31  33  39  45  Sat
2   11  16  21  25  28  Wed
17  21  24  37  46  48  Mon
6   10  11  22  28  33  Sat
3   10  23  30  38  45  Wed

我试图创建一个脚本,它会给我当天重复的最多6个数字。

下面的这个脚本将给出我为第一列重复的所有数字。

$query = mysqli_query($connect_db,"SELECT first, COUNT(first) AS ct
FROM numbers
GROUP BY first
ORDER BY first DESC");
        while($row = mysqli_fetch_array($query)){
        echo '<table class="first"><tr><td>'. $row[1].'</td><tr></table>';

        }

但我只需要6个重复次数最多的数字。

数据库: enter image description here

2 个答案:

答案 0 :(得分:1)

好的,我想我现在明白了这个问题。试试这个。

$numLabels = array('first', 'second', 'third', 'fourth', 'fifth', 'sixth');

$numbers= array();

$query = "SELECT * FROM numbers";
$rows = mysqli_query($link, $query);

if ($rows) {
    while ($row = mysqli_fetch_assoc($rows)) {

        //indexing all the numbers and counting occurrences
        foreach ($numLabels as $label) {
            if (isset($numbers[$row['day']][$row[$label]])) {
                $numbers[$row['day']][$row[$label]] ++;
            } else {
                $numbers[$row['day']][$row[$label]] = 1;
            }
        }
    }

    mysqli_free_result($rows);

    //sorting by occurrences
    foreach (array_keys($numbers) as $key) {
        arsort($numbers[$key]);
    }

    //getting the most common 6
    foreach ($numbers as $day => $dayNumbers) {
        $numbers[$day] = array_slice(array_keys($dayNumbers), 0, 6);
    }
}

//example output format: "Day: num1-num2-num3..."
foreach ($numbers as $day => $dayNumbers) {
    echo $day . ': ' . implode('-', $dayNumbers) . '<br />';
}

答案 1 :(得分:0)

您使用六列来表示基本上属于单个属性的内容;这就是为什么你想要的结果如此尴尬。如果您的表已规范化,查询将更多更简单。这是一个可能的表格设计,比当前表更加规范化

+-----+--------+----------+-----+
| id  | number | position | day |
+-----+--------+----------+-----+
| 1   | 1      | 1        | Mon |
| 1   | 5      | 2        | Mon |
| 1   | 8      | 3        | Mon |
| 1   | 14     | 4        | Mon |
| 1   | 35     | 5        | Mon |
| 1   | 45     | 6        | Mon |
| 2   | 13     | 1        | Sat |
| 2   | 26     | 2        | Sat |
| 2   | 30     | 3        | Sat |
| 2   | 31     | 4        | Sat |
| ... | ...    | ...      | ... |
+-----+--------+----------+-----+

使用此表格,每天按频率对数字进行排序很简单:

SELECT
  day,
  number,
  COUNT(number) AS count
FROM
  table
GROUP BY day
ORDER BY COUNT(number) DESC;

有关在上述查询中限制每个组内结果的深入讨论,您可以阅读How to select the first/least/max row per group in SQLUNION方法可能是最佳选择,因为您似乎只有三个可能的值day可以分组(在任何情况下最多七个):

(SELECT number, day FROM table WHERE day='Mon'
 GROUP BY day ORDER BY COUNT(number) DESC LIMIT 6)
UNION ALL
(SELECT number, day FROM table WHERE day='Wed'
 GROUP BY day ORDER BY COUNT(number) DESC LIMIT 6)
UNION ALL
(SELECT number, day FROM table WHERE day='Sat'
 GROUP BY day ORDER BY COUNT(number) DESC LIMIT 6)

您需要(day, number)上的复合索引才能获得最佳效果。使用此解决方案,您可以避免将整个表从数据库传输到PHP脚本的开销。随着表的大小增加,这变得越来越重要。 SELECT * FROM table代码味道很强。

还有其他方法可以设计规范化表来存储此类数据;例如,我更喜欢存储日历日期并从中导出星期几,而不是仅存储星期几的缩写。但最重要的是将您的数字放入一个属性中,这样您就可以将它们视为同类数据。