I have two tables. I would like to get the values of the counts of these two rows (attacker, victim) from the first table and their respective userid from the second table, if possible.
Table1:
id----attacker---victim 1-----1216-------1040 1-----1216-------1024 1-----1040-------1024 1-----1040-------1024 1-----1024-------1216 1-----1216-------1024
Table2:
id----name----userid 1-----John----1216 2-----Joe-----1024 3-----Peter---1040
So far I only managed to get the values of the counts of rows attacker and victim but I achieved it using two separate queries. Is it possible to do this with just one query?
$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();
Basically what I am aiming for is to get something like this in the end:
name----------(count of attacker)-----(count of victim) John-----------3----------------------1 Joe------------1----------------------4 Peter----------2----------------------1
UPDATE:
After some time I managed to get name + victims and name + attackers but separate by using the code below:
$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();
Advertisement
Answer
After some hours of researching I think I somehow managed to find a solution. I just had to use relationships.
On Table 2 Model:
public function kills()
{
    return $this->hasMany('Kill', 'attacker', 'userid');
}
public function deaths()
{
    return $this->hasMany('Kill', 'victim', 'userid');
}
then I used the following code to get the results I wanted:
$results = Table2::select('name')
            ->whereHas('kills')->orWhereHas('deaths')
            ->withCount(['kills'=> $query])
            ->withCount(['deaths'=> $query])
            ->orderBy('kills_count', 'desc')
            ->get();
return $results->toArray();
I’ll also post the RAW SQL query incase anyone could benefit from it
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
If anyone knows how to further improve this query for performance, please let me know.