Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从表中获取3个最高值_Php_Mysql - Fatal编程技术网

Php 从表中获取3个最高值

Php 从表中获取3个最高值,php,mysql,Php,Mysql,我想数一数拥有最多属性行的前3个用户 SQL表: ID | IdUser | Type | ----------------------- 0 | 1 | like | 1 | 1 | like | 2 | 4 | dislike | 3 | 5 | dislike | 4 | 1 | like | 5 | 4 | like | 6 | 5 | like | 8 | 4

我想数一数拥有最多属性行的前3个用户

SQL表:

ID | IdUser |  Type   |
-----------------------
0  |    1   |  like   |
1  |    1   |  like   |
2  |    4   | dislike |
3  |    5   | dislike |
4  |    1   |  like   |
5  |    4   |  like   |
6  |    5   |  like   |
8  |    4   |  like   |
9  |    4   |  like   |
10 |    3   |  like   |
11 |    5   |  like   |
12 |    9   |  like   |
结果应该是:

idUser[1] with 3 times "like" and 0 "dislike" (3-0 = 3 points)
idUser[4] with 3 times "like" and 1 "dislike" (3-1 = 2 points)
idUser[5] with 2 times "like" and 1 "dislikes (2-1 = 1 point )
所以我要做的是用他们的分数得到idUser 1(3分),然后是idUser 4(2分),最后是idUser 5(1分)

我试过不同的方法,但都不管用

在这里,我试图创建一个包含所有数据的二维数组,然后获得最高值,但我无法完成第二部分

表“用户”包含网站的所有用户 表“点”记录了喜欢和不喜欢的内容

$sqlUsers = "SELECT * FROM users";
$resultUsers = $conn->query($sqlUsers);

$recordsArray = array(); //create array

while($rowUsers = $resultUsers->fetch_assoc()) {

    $idUser = $rowUsers['id'];

    //COUNT LIKES OF THE USER
    $sqlLikes = "SELECT COUNT(id) AS numberLikes FROM points WHERE idCibledUser='$idUser' AND type='like'";
    $resultLikes = $conn->query($sqlLikes);
    $rowLikes = $resultLikes->fetch_assoc();

    //COUNT DISLIKES OF THE USER
    $sqlDislikes = "SELECT COUNT(id) AS numberDislikes FROM points WHERE idCibledUser='$idUser' AND type='dislike'";
    $resultDislikes = $conn->query($sqlDislikes);
    $rowDislikes = $resultDislikes->fetch_assoc();

    //GET POINTS BY SUBTRACTING DISLIKES FROM LIKES
    $points = $rowLikes['numberLikes'] - $rowDislikes['numberDislikes'];

    $recordsArray[] = array($idUser => $points);

}

如果您需要经常获取喜欢/不喜欢的内容,请参阅下面的解决方案,
表经常更新,数据相关性很重要,即您不想缓存结果

创建另一个表,如
user\u points\u summary
,该表将有两列,例如
IdUser
points
IdUser
要在此表中唯一,必须在向
表中添加新行时触发
重新计算(每个用户)

如果需要喜欢/不喜欢细分,则此表将有3列-
IdUser
(不再唯一)、
likes\u count
dislikes\u count
。然后相同-在插入/更新/删除
表中的行时触发此表更新

如果使用第二个选项(使用喜欢/不喜欢细分)-下面是CREATETABLE语句的示例:

CREATE TABLE `user_points_summary` (
  `IdUser` int(11) NOT NULL,
  `likes_count` int(11) NOT NULL DEFAULT '0',
  `dislikes_count` int(11) NOT NULL DEFAULT '0',
  KEY `idx_user_points_summary_IdUser` (`IdUser`)
) ENGINE=InnoDB;
然后,您可以将以下触发器添加到
users
表中,该表将在添加新用户时添加零喜欢/不喜欢:

CREATE TRIGGER `users_AFTER_INSERT` AFTER INSERT ON `users` FOR EACH ROW
BEGIN
    INSERT INTO `user_points_summary` VALUE (NEW.`IdUser`, 0, 0);
END
然后将以下触发器添加到
表中,以更新
用户点_摘要
喜欢/不喜欢计数:

DELIMITER $$
CREATE TRIGGER `points_AFTER_INSERT` AFTER INSERT ON `points` FOR EACH ROW
BEGIN
    IF NEW.`Type` = 'like' THEN
        UPDATE `user_points_summary` SET `likes_count` = `likes_count` + 1 WHERE `IdUser` = NEW.`IdUser`;
    ELSEIF NEW.`Type` = 'dislike' THEN
        UPDATE `user_points_summary` SET `dislikes_count` = `dislikes_count` + 1 WHERE `IdUser` = NEW.`IdUser`;
    END IF;
END $$

CREATE TRIGGER `points_AFTER_UPDATE` AFTER UPDATE ON `points` FOR EACH ROW
BEGIN
    IF NEW.`Type` = 'dislike' AND OLD.`Type` = 'like' THEN
        UPDATE `user_points_summary`
            SET 
                `likes_count` = `likes_count` - 1,
                `dislikes_count` = `dislikes_count` + 1
        WHERE `IdUser` = `OLD`.`IdUser`;
    ELSEIF NEW.`Type` = 'like' AND OLD.`Type` = 'dislike' THEN
        UPDATE `user_points_summary`
            SET 
                `dislikes_count` = `dislikes_count` - 1,
                `likes_count` = `likes_count` + 1
        WHERE `IdUser` = OLD.`IdUser`;
    END IF;
END $$

CREATE TRIGGER `points_AFTER_DELETE` AFTER DELETE ON `points` FOR EACH ROW
BEGIN
    IF OLD.`Type` = 'like' THEN
        UPDATE `user_points_summary`
            SET `likes_count` = `likes_count` - 1
        WHERE `IdUser` = `OLD`.`IdUser`;
    ELSEIF OLD.`Type` = 'dislike' THEN
        UPDATE `user_points_summary`
            SET `dislikes_count` = `dislikes_count` - 1
        WHERE `IdUser` = OLD.`IdUser`;
    END IF;
END $$
DELIMITER ;
SELECT *, `likes_count` - `dislikes_count` AS `points` 
FROM `user_points_summary`
ORDER BY `points` DESC
LIMIT 3
然后,您可以使用以下查询获取具有“喜欢”和“不喜欢”计数的用户点:

DELIMITER $$
CREATE TRIGGER `points_AFTER_INSERT` AFTER INSERT ON `points` FOR EACH ROW
BEGIN
    IF NEW.`Type` = 'like' THEN
        UPDATE `user_points_summary` SET `likes_count` = `likes_count` + 1 WHERE `IdUser` = NEW.`IdUser`;
    ELSEIF NEW.`Type` = 'dislike' THEN
        UPDATE `user_points_summary` SET `dislikes_count` = `dislikes_count` + 1 WHERE `IdUser` = NEW.`IdUser`;
    END IF;
END $$

CREATE TRIGGER `points_AFTER_UPDATE` AFTER UPDATE ON `points` FOR EACH ROW
BEGIN
    IF NEW.`Type` = 'dislike' AND OLD.`Type` = 'like' THEN
        UPDATE `user_points_summary`
            SET 
                `likes_count` = `likes_count` - 1,
                `dislikes_count` = `dislikes_count` + 1
        WHERE `IdUser` = `OLD`.`IdUser`;
    ELSEIF NEW.`Type` = 'like' AND OLD.`Type` = 'dislike' THEN
        UPDATE `user_points_summary`
            SET 
                `dislikes_count` = `dislikes_count` - 1,
                `likes_count` = `likes_count` + 1
        WHERE `IdUser` = OLD.`IdUser`;
    END IF;
END $$

CREATE TRIGGER `points_AFTER_DELETE` AFTER DELETE ON `points` FOR EACH ROW
BEGIN
    IF OLD.`Type` = 'like' THEN
        UPDATE `user_points_summary`
            SET `likes_count` = `likes_count` - 1
        WHERE `IdUser` = `OLD`.`IdUser`;
    ELSEIF OLD.`Type` = 'dislike' THEN
        UPDATE `user_points_summary`
            SET `dislikes_count` = `dislikes_count` - 1
        WHERE `IdUser` = OLD.`IdUser`;
    END IF;
END $$
DELIMITER ;
SELECT *, `likes_count` - `dislikes_count` AS `points` 
FROM `user_points_summary`
ORDER BY `points` DESC
LIMIT 3

如果您最终只需要总分,而不需要对喜欢和不喜欢进行细分(您的问题不完全清楚):

如果您想要完整的细分:

SELECT IdUser,
       SUM(IF(Type='like',1,-1)) AS points,
       SUM(IF(Type='like',1,0)) as likes,
       SUM(IF(Type='dislike',1,0)) as dislikes
FROM users
GROUP BY IdUser
ORDER BY points DESC
LIMIT 3
解释

假设我想计算
Type
列的值为
'like'
的行总数。我可以执行以下操作:

SELECT COUNT(*) AS cnt FROM users WHERE Type = 'like'
SELECT SUM(IF(Type = 'like', 1, 0)) AS cnt FROM users
但另一种可能不那么直接的方式是:

SELECT COUNT(*) AS cnt FROM users WHERE Type = 'like'
SELECT SUM(IF(Type = 'like', 1, 0)) AS cnt FROM users
在上面的SQL中,检查每行中的
Type
列,如果等于
'like'
,则将值1分配给该列,否则为0。然后使用
SUM
函数将所有这些1和0相加。通过将所有的1相加,实际上是在计算
类型
列中具有
'like'
的行数。第二种方法允许您一次处理喜欢和不喜欢的数量:

SELECT SUM(IF(Type = 'like', 1, 0)) AS likes,
       SUM(IF(Type = 'dislike', 1, 0)) AS dislikes
       FROM users
但是,如果您希望逐个用户获得上述计数,该怎么办?这就是
分组依据
条款的目的:

SELECT IdUser,
       SUM(IF(Type = 'like', 1, 0)) AS likes,
       SUM(IF(Type = 'dislike', 1, 0)) AS dislikes
       FROM users
       GROUP BY IdUser
如果我们将值1分配给包含
'like'
的列,并将值-1分配给包含
'loke'
(或不是
'like'
)的列,然后将这些值相加,则可以计算“分数”或喜欢与不喜欢之间的差异:

SELECT IdUser,
       SUM(IF(Type = 'like', 1, -1)) AS points,
       SUM(IF(Type = 'like', 1, 0)) as likes,
       SUM(IF(Type = 'dislike', 1, 0)) as dislikes
FROM users
GROUP BY IdUser
最后,如果您想要三个最高分,请按降序对返回的行进行排序(
order BY points DESC
),并仅保留返回的前3行(
LIMIT 3
):


你能展示一下你的尝试和结果吗?@PatrickQ我刚刚编辑了我的帖子。有任何答案解决了这个问题吗?到目前为止,您已经收到了两条消息。警告:您对参数化预处理语句非常开放,应该使用参数化预处理语句,而不是手动生成查询。它们由或提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行。我不认为你的问题是关于mysqli的。我要把它改成MySQL tag,第二个代码正是我所需要的!谢谢你的回答。但是我想知道它是怎么工作的,你能给我一些简单的解释吗?我明白了。再次感谢:)是的,@Booboo回答了我的问题,但你的代码仍然很有趣。我只是想知道mysql必须执行的任务是否变得太重要了,尤其是在有几百个数据库的情况下entries@Azelkan是的,你是对的,有几百个条目,我的解决方案就太过分了