【问题标题】:PHP Compare column values and edit database accordinglyPHP比较列值并相应地编辑数据库
【发布时间】:2017-09-03 00:31:43
【问题描述】:

我是 PHP 的新手,我被困在某个点上。我尝试为它寻找解决方案,但是我没有找到我真正需要的东西。

我的目标是创建一个排行榜,其中值按降序显示,并显示排名和分数。此外,它还应该显示是否存在平局。

数据库应如下所示:

+---------+------+----------------+-------+------+
| user_id | name | email          | score | tied |
+---------+------+----------------+-------+------+
| 1       | SB   | sb@gmail.com   | 1     | 0    |
+---------+------+----------------+-------+------+
| 2       | AS   | as@web.de      | 2     | 0    |
+---------+------+----------------+-------+------+
| 3       | BR   | br@yahoo.com   | 5     | 1    |
+---------+------+----------------+-------+------+
| 4       | PJ   | pj@gmail.com   | 5     | 1    |
+---------+------+----------------+-------+------+

输出的表格应该是这样的:

+------+-------------+-------+------+
| rank | participant | score | tied |
+------+-------------+-------+------+
| 1    | BR          | 5     | Yes  |
+------+-------------+-------+------+
| 2    | PJ          | 5     | Yes  |
+------+-------------+-------+------+
| 3    | AS          | 2     | No   |
+------+-------------+-------+------+
| 4    | SB          | 1     | No   |
+------+-------------+-------+------+

我设法以正确的顺序显示了排名、参与者和分数。但是,我不能让tied 列按我想要的方式工作。只要两行(不)具有相同的值,它就应该更改值。

表格是通过在通常的html中创建<table><thead>来构造的,但是<tbody>是通过需要一个动态创建表格内容的php文件来创建的。

正如在 createTable 代码中所见,我尝试通过将当前行与前一行进行比较来解决此问题。但是,这种方法只会导致我遇到语法错误。我的想法是我不能在 SQL 查询中使用 php 变量,而且我的知识还不足以自己解决问题。我也没有通过研究找到解决方案。

我对这种方法的另一个担忧是它不会根据所有值检查所有值。它只检查一个与前一个,因此它不会将第一个与第三个进行比较。

我的问题是如何用我的方法完成任务,或者,如果我的方法完全错误,我该如何找到另一条路线的解决方案。

index.php

<table class="table table-hover" id="test">
    <thead>
        <tr>
            <th>Rank</th>
            <th>Participant</th>
            <th>Score</th>
            <th>Tied</th>
        </tr>
    </thead>

    <tbody>
        <?php
            require("./php/createTable.php");
        ?>
    </tbody>
</table>

createTable.php

<?php
    // Connection
    $conn = new mysqli('localhost', 'root', '', 'ax');
    if ($conn->connect_error) {
        die("Connection failed: " . $conn->connect_error);
    }

    // SQL Query
    $sql = "SELECT * FROM names ORDER BY score DESC";
    $result = $conn->query("$sql");

    // Initalizing of variables
    $count = 1;
    $previous = '';

    while($row = mysqli_fetch_array($result)) {
        $current = $row['score'];
        $index = $result['user_id']

        if ($current == $previous) {
            $update = "UPDATE names SET tied=0 WHERE user_id=$index";
            $conn->query($update);
        }
        $previous = $current;
?>

<tr>
    <td>
        <?php 
            echo $count; 
            $count++;
        ?>
    </td>
    <td><?php echo $row['name'];?></td>
    <td><?php echo $row['score'];?></td>
    <td>
        <?php
            if ($row['tied'] == 0) {
                echo 'No';
            } else{
                echo 'Yes';
            }
        ?>

    </td>
</tr>

<?php
}
?>

【问题讨论】:

  • “每当两行(不)具有相同的值”?你什么意思 ?将值更改为什么?
  • 警告:当使用mysqli 时,您应该使用parameterized queriesbind_param 将用户数据添加到您的查询中。 请勿使用字符串插值或连接来完成此操作,因为您创建了严重的SQL injection bug切勿$_POST$_GET任何用户数据直接放入查询中,如果有人试图利用您的错误,这可能会非常有害。
  • @deg,是的。例如,如果 PJ 的“分数”变量更改为 8,则不存在平局。因此,tied 两个列都应该更改为“否”(或者更确切地说是 0)。
  • @tadman 感谢您的建议!待我解决当前问题后,我会修复这些错误。
  • 请记住,第一次正确操作通常会在这些错误有机会发生之前解决它们。

标签: php mysql sql database compare


【解决方案1】:

我认为问题出在这里

 $index = $result['user_id'];

应该是

 $index = $row['user_id'];

更新绑定后,您应该再次从数据库中检索它

【讨论】:

  • 谢谢。但是,它仍然不能解决比较问题,因为其中一个绑定值返回“否”,因为它与 0 进行比较。或者例如如果表格在底部行有平局,则这些值之一也是“否”,因为该值与前一个值进行了比较(例如$previous = 10$current = 5,它将为$current 返回“否”。但是,如果下一个值也是 5,则“否”将是错误的。
【解决方案2】:

所以我自己解决了我的问题,提出了一种不同的方法。

首先我删除了这部分:

$current = $row['score'];
    $index = $result['user_id']

    if ($current == $previous) {
        $update = "UPDATE names SET tied=0 WHERE user_id=$index";
        $conn->query($update);
    }
    $previous = $current;

还有previous 变量。

我的新方法将整个表保存在一个新数组中,使用 array_count_values() 方法获取重复值,然后使用 array_keys() 方法获取键,并通过 SQL 查询更新数据库。

这是更改部分的代码:

// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");

$query = "SELECT * FROM names ORDER BY score DESC";
$sol = $conn->query("$query");

// initalizing of variables
$count = 1;
$data = array();

// inputs table into an array
while($rows = mysqli_fetch_array($sol)) {
    $data[$rows['user_id']] = $rows['score'];
}

// -- Tied Column Sort --

// counts duplicates
$cnt_array = array_count_values($data);

// sets true (1) or false (0) in helper-array ($dup)
$dup = array();
foreach($cnt_array as $key=>$val){
   if($val == 1){
      $dup[$key] = 0;
   }
   else{
      $dup[$key] = 1;
   }
}

// gets keys of duplicates (array_keys()) and updates database accordingly ($update query)
foreach($dup as $key => $val){
    if ($val == 1) {
        $temp = array_keys($data, $key);

        foreach($temp as $k => $v){
            $update = "UPDATE names SET tied=1 WHERE user_id=$v";
            $conn->query($update);
        }
    } else{
        $temp = array_keys($data, $k);

        foreach($temp as $k => $v){
            $update = "UPDATE names SET tied=0 WHERE user_id=$v";
            $conn->query($update);
        }
    }
}

感谢大家的回答并帮助我找到解决方案。

【讨论】:

    【解决方案3】:

    使用类似的东西代替更新代码

    $query = "select score, count(*) as c from names group by score having c > 1";
    

    然后您将获得平局的分数,使用这些分数更新记录并完成。确保首先将所有行的 tie 设置为 0,然后运行此解决方案

    更新更快的基于 sql 的解决方案:

    首先重置数据库:

    $update = "UPDATE names SET tied=0";
    $conn->query($update);
    

    所有记录现在都有一个tie = 0 值。接下来更新所有平局的记录

    $update = "update docs set tied = 1 where score IN (
        select score from docs
        group by score having count(*) > 1)";
    $conn->query($update);
    

    由于我们选择具有两条或更多记录的所有分数并使用这些分数更新所有记录,所有具有平局的记录现在都已平局 = 1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-25
      • 2020-07-16
      • 1970-01-01
      相关资源
      最近更新 更多