【问题标题】:(Laravel) Multiple counts, group by on same table with one query(Laravel)多个计数,通过一个查询在同一张表上分组
【发布时间】:2020-11-29 04:21:28
【问题描述】:

我有两张桌子。如果可能的话,我想从第一个表中获取这两行(攻击者、受害者)的计数值,并从第二个表中获取它们各自的用户 ID。

表1:

id----attacker---victim
1-----1216-------1040
1-----1216-------1024
1-----1040-------1024
1-----1040-------1024
1-----1024-------1216
1-----1216-------1024

表2:

id----name----userid
1-----John----1216
2-----Joe-----1024
3-----Peter---1040

到目前为止,我只设法获得了攻击者和受害者的行计数值,但我使用两个单独的查询来实现它。是否可以只用一个查询来做到这一点?

$victims = DB::table('Table1')
    ->select(DB::raw('victim as userid, count(victim) as victims'))
    ->where('victim', '<>', 1)
    ->groupBy('victim')
    ->get();

$attackers = DB::table('Table1')
    ->select(DB::raw('attacker as userid, count(attacker) as attackers'))
    ->where('attacker', '<>', 1)
    ->groupBy('attacker')
    ->get();

基本上我的目标是最终得到这样的东西:

name----------(count of attacker)-----(count of victim)
John-----------3----------------------1
Joe------------1----------------------4
Peter----------2----------------------1

更新:

一段时间后,我设法获得了姓名+受害者和姓名+攻击者,但使用以下代码将它们分开:

$kills = DB::table('Table2')
    ->join('Table1', 'Table2.roleid', '=', 'Table1.attacker')
    ->select(DB::raw('Table2.name, count(Table1.attacker) as kills'))
    ->groupBy('Table2.name')
    ->orderBy('kills', 'desc')
    ->get();

$deaths = DB::table('Table2')
    ->join('Table1', 'Table2.roleid', '=', 'Table1.victim')
    ->select(DB::raw('Table2.name, count(Table1.victim) as deaths'))
    ->groupBy('Table2.name')
    ->orderBy('deaths', 'desc')
    ->get();

【问题讨论】:

  • 你可以试试这个 raw sql select table2.name, count(table1.victim),count(table1.attacker) from table2 LEFT JOIN table1 t1 ON t1.attacker = table2.user_id LEFT JOIN table1 t0 ON t0.victim =table2.user_id
  • @Abdel-azizhassan 它导致错误:#1054 - '字段列表'中的未知列'table1.victim'
  • 你可以使用 Table1 和 Table2 而不是小写,但也要确保 table1 有一个名为victim的列
  • 我有一些进展。我添加了对原始问题的更新。我设法得到了姓名+受害者和姓名+攻击者,但又一次......分开了。有什么方法可以在单个查询中做到这一点?
  • 您能否将您的架构发布到问题中:))

标签: sql laravel join count


【解决方案1】:

经过几个小时的研究,我想我设法找到了解决方案。我只需要使用关系。

在表 2 模型上:

public function kills()
{
    return $this->hasMany('Kill', 'attacker', 'userid');
}

public function deaths()
{
    return $this->hasMany('Kill', 'victim', 'userid');
}

然后我用下面的代码得到了我想要的结果:

$results = Table2::select('name')
            ->whereHas('kills')->orWhereHas('deaths')
            ->withCount(['kills'=> $query])
            ->withCount(['deaths'=> $query])
            ->orderBy('kills_count', 'desc')
            ->get();

return $results->toArray();

我还将发布 RAW SQL 查询,以防任何人都可以从中受益

SELECT
   `name`,
   (
      SELECT
         COUNT(*) 
      FROM
         `Table1` 
      WHERE
         `Table2`.`userid` = `Table1`.`attacker` 
   )
   AS `kills_count`,
   (
      SELECT
         COUNT(*) 
      FROM
         `Table1` 
      WHERE
         `Table2`.`userid` = `Table1`.`victim` 
   )
   AS `deaths_count` 
FROM
   `Table2` 
WHERE
   EXISTS 
   (
      SELECT
         * 
      FROM
         `Table1` 
      WHERE
         `Table2`.`userid` = `Table1`.`attacker` 
   )
   OR EXISTS 
   (
      SELECT
         * 
      FROM
         `Table1` 
      WHERE
         `Table2`.`userid` = `Table1`.`victim` 
   )
ORDER BY
   `kills_count` DESC

如果有人知道如何进一步改进此查询的性能,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 2018-03-26
    • 2012-11-05
    • 2018-11-25
    • 2012-12-14
    • 2015-06-05
    • 2012-12-04
    相关资源
    最近更新 更多