php - 具有多个 COUNT() 的多个 LEFT JOINS 对所有列进行计数

标签 php mysql join count left-join

我有 4 张 table 。

表组

| ID | NAME |
  1    Premium
  2    Silver

表用户

| ID | group_id | NAME |
  1       1      Serhan
  2       2      Farhat

表用户统计

| ID | user_id | TYPE |
  1       1      1
  2       2      0

表投票

| ID | user_id | VOTE |
  1       1      1
  2       2      0
  3       1      0

我创建了一个 SQL 查询来检索同一组中的用户详细信息。成功了!然后我想检索已投票给组中用户的任何投票。我想统计选票。所以基本上我已经做了这个sql查询。

global $conn;
$res_groups = array();
$stmt = $conn->prepare("
    SELECT * FROM groups
");
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($group = $stmt->fetch()){
    $groups = array();
    $groups['id'] = $group['id'];
    $groups['name'] = $group['name'];

    $user_arr = array();
    $stmts = $conn->prepare('
        SELECT l.*,
        (SELECT MAX(ls.date) from user_statistics ls WHERE ls.user_id = l.id GROUP BY ls.user_id) as ls_date,
        (SELECT SUM(IF(ls.type="0", ls.type, 0)) FROM user_statistics ls WHERE ls.user_id = l.id GROUP BY ls.user_id) as ls_us,
        (SELECT SUM(IF(ls.type="1", ls.type, 0)) FROM user_statistics ls WHERE ls.user_id = l.id  GROUP BY ls.user_id) as ls_uk,
        (SELECT COUNT(*) FROM user_statistics WHERE type="1" AND ls.user_id = l.id GROUP BY ls.user_id) as totals,
        (SELECT COUNT(*) FROM votes v WHERE v.vote=0 AND confirm=0 AND v.user_id = l.id) as badvote,
        (SELECT COUNT(*) FROM votes v WHERE v.vote=1 AND confirm=0 AND v.user_id = l.id) as goodvote
        FROM user l
        LEFT JOIN
        user_statistics ls on l.id = ls.user_id
        LEFT JOIN votes v on v.user_id = l.id
        WHERE l.group_id = '.$groups['id'].' AND status = 1
        GROUP BY l.id,ls.user_id
    ');
    $stmts->execute();
    $stmts->setFetchMode(PDO::FETCH_ASSOC);
    while ($usr = $stmts->fetch()){

        $totalvote=($usr['badvote']+$usr['goodvote']);
        if($totalvote>0){
            $badvote=bcdiv($usr['badvote']*100/$totalvote,1,2);
            $goodvote=bcdiv($usr['goodvote']*100/$totalvote,1,2);
        }else{
            $badvote=0;
            $goodvote=0;
        }
        $votes[] = array(
            "count" => $usr['badvote'],
            "percent" => $badvote
        );
        $votes[] = array(
            "count" => $usr['goodvote'],
            "percent" => $goodvote
        );

        $user_arr[] = array(
            "id" => $usr['id'],
            "group_id" => $usr['group_id'],
            "name" => $usr['name'],
            "votes_summary" => $votes
        );
    }
    $groups['list'] = $user_arr;
    $res_groups[] = $groups;
}

所有代码似乎都可以工作,除非有一件事。投票总是返回以计算数据库投票中的所有列并将数据应用于我的所有用户。我想要的是根据投票类型 GOOD 或 BAD 获得每个用户获得的投票数。

任何帮助都会很好。

最佳答案

查看您的代码,您可以重构您的查询,避免为每一行选择一个子查询,并在连接中使用两个带有 group by 的子查询。

您也有相同的坏票和好票代码,可能您需要不同的代码来获取不同的值

    SELECT l.*
      , t1.ls_date
      , t1.ls_us
      , t1.ls_uk
      , t2.totals
      , t2.badvote
      , t2.goodvote
    FROM user l
    INNER JOIN  (
     SELECT ls.user_id
        , MAX(ls.date) ls_date
        , SUM(IF(ls.type="0", ls.type, 0)) ls_us
        , SUM(IF(ls.type="1", ls.type, 0)) ls_uk
     from user_statistics ls 
     GROUP BY ls.user_id 
    )  t1 on t1.user_id = l.id
    LEFT JOIN ( 
        SELECT v.user_id
        , sum( case when type="1" then 1 else 0 end ) totals
        /* these are the same */
        , sum ( case when v.vote=1 AND confirm=0  then 1 else 0 END ) badvote  
        /* these are the same */
        , sum ( case when v.vote=1 AND confirm=0  then 1 else 0 END ) goodvote 
      FROM votes v
    ) t2 ON t2.user_id  = l.id 
    WHERE l.group_id = '.$groups['id'].' 
    AND status = 1

并且您应该避免在 SQL 中使用 PHP var(您面临 SQL 注入(inject)的风险)。为此,您应该查看数据库驱动程序以获取准备好的语句和绑定(bind)值,或者至少确保正确清理 php var 内容

关于php - 具有多个 COUNT() 的多个 LEFT JOINS 对所有列进行计数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59200626/

相关文章:

php - 如何在 Web 应用程序中处理和/或存储货币值?

php - 递归 chmod/chown/chgrp 目录中的所有文件和文件夹

mysql - 如何在mysql中存储常量

mysql - 使用pt-online-schema-change工具时,原表的索引可以保留吗?

python - 我无法使用 python 在 mysqldb 中分配主键或外键。

sql - 仅当列为 NULL 时加入

php - 在MySQL中连接一个 'blog'表和 'comments'表

java - 任何人都有一个很好的解决方案来抓取带有用 Javascript 生成的内容(在本例中为 HTML 表格)的页面的 HTML 源代码?

php - Zend_Mail 中的 UTF-8 发件人姓名?

sql - 使用 2 个键加速连接