计算每行中真实值的数量

Posted

技术标签:

【中文标题】计算每行中真实值的数量【英文标题】:Count number of true values in each row 【发布时间】:2016-09-19 06:25:30 【问题描述】:

我使用 phpMyAdmin 创建了一个 mysql 数据库,该数据库存储用户在网页上选择的数据。基本上,用户可以点击页面上的按钮,当他们被点击时,数据库中的相应列从0变为1。但是,我只希望每个用户最多可以选择6个选项。 例如:

idopt1opt2opt3opt4opt5opt6opt7opt8总计 0     1     0     0     0     1     1     0     3      1     1     1     1     0     1     0     1     6      1     0     0     0     0     0     0     0     1     

“id”代表每个单独的用户,“opt#”是他们选择的选项,“total”是选择的选项数量。

我使用的代码是

//$id is the id of the user that is logged in
$total=$row['total']; //Fetch data from column 'total' for logged in user
$choice=$_GET['opt']; //Set 'choice' variable to value submitted by button
$selected=$row[$choice]; //Fetch value of corresponding column

if ($total>= 6)    
    echo "Too many selected";   

elseif (!$selected) 
    mysqli_query($con,"UPDATE `choices` SET `$choice` = '1', `total` = total+1 WHERE `choices`.`id` = '$id'");

else 
    echo "You have already selected this";
;

此代码运行良好,并且在 count 等于 6 时阻止数据库更新,但我担心用户可能会修改该值,因为选择的选项比他们应该的要多,或者当我添加时可能会出现问题允许用户取消选择选项的代码。

是否可以通过计算值为 1 的“opt#”列的数量而不是每次用户选择另一个选项时加 1 来使“total”列自动更新?我想这将涉及添加值,但由于我是 PHP 和 MySQL 的初学者,我不确定我必须使用什么代码来实现它。

希望我的问题不会太令人困惑(我很乐意澄清任何事情)。谢谢。

【问题讨论】:

【参考方案1】:

如果您使用 MariaDB(更好的 MySQL),您可以创建一个虚拟列来保存 6 个字段的总和。它会自动更新,您也可以在上面添加索引。

CREATE TABLE table1 (
     id INT NOT NULL,
     opt1 int DEFAULT '0',
     opt2 int DEFAULT '0',
     opt3 int DEFAULT '0',
     opt4 int DEFAULT '0',
     opt5 int DEFAULT '0',
     opt6 int DEFAULT '0',
     total INT AS (opt1+opt2+opt3+opt4+opt5+opt6) PERSISTENT);

参见手册:https://mariadb.com/kb/en/mariadb/virtual-computed-columns/

示例

MariaDB [bb]> CREATE TABLE table1 (
    ->      id INT NOT NULL,
    ->      opt1 int DEFAULT '0',
    ->      opt2 int DEFAULT '0',
    ->      opt3 int DEFAULT '0',
    ->      opt4 int DEFAULT '0',
    ->      opt5 int DEFAULT '0',
    ->      opt6 int DEFAULT '0',
    ->      total INT AS (opt1+opt2+opt3+opt4+opt5+opt6) PERSISTENT);
Query OK, 0 rows affected (0.50 sec)

MariaDB [bb]> insert into table1 (opt3,opt4) VALUES (1,1);
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [bb]> insert into table1 (opt3) VALUES (1);
Query OK, 1 row affected, 1 warning (0.00 sec)

MariaDB [bb]> insert into table1 (opt1) VALUES (1);
Query OK, 1 row affected, 1 warning (0.01 sec)

MariaDB [bb]> select * from table1;
+----+------+------+------+------+------+------+-------+
| id | opt1 | opt2 | opt3 | opt4 | opt5 | opt6 | total |
+----+------+------+------+------+------+------+-------+
|  0 |    0 |    0 |    1 |    1 |    0 |    0 |     2 |
|  0 |    0 |    0 |    1 |    0 |    0 |    0 |     1 |
|  0 |    1 |    0 |    0 |    0 |    0 |    0 |     1 |
+----+------+------+------+------+------+------+-------+
3 rows in set (0.04 sec)

MariaDB [bb]>

【讨论】:

MySQL (5.7.6) 也支持generated columns。从 5.7.8 开始可以对虚拟列进行索引。【参考方案2】:

这是真正的问题/解决方案吗?思考以下...

您发布您的用户界面。很快,一个“用户”打电话给你抱怨:“我点击了一个按钮,但什么也没发生!”。首先,您盯着代码看是否有问题。然后你记得你的“6”限制并问他们是否有 6。用户离开时要么尴尬要么生气 UI 没有让它更明显。

然后你意识到你需要一个弹出窗口,或者让“total=6”闪烁,或者其他什么东西,这样投诉就不会再出现了。

换句话说,从创建一个友好的用户界面开始,然后再看看需要什么 SQL。

完成此操作后,您可能会决定省略“总计”列。

【讨论】:

以上是关于计算每行中真实值的数量的主要内容,如果未能解决你的问题,请参考以下文章

用 pentaho 计算每列空值的数量

Python/Pandas:计算每行中缺失/NaN 的数量

计算一行中空值的数量以除以(未知)列数

在大熊猫数据框中计算每行历史值的最有效方法是啥?

如何计算 NumPy bool 数组中真实元素的数量

计算数据帧 Spark 中缺失值的数量