一对多计算一次查询?

One to Many Count with one query?

我有一段时间没有接触后端了.. 如果这太简单了,请原谅我。我正在使用 Lumen v.5.6.1。

| table.sets     |    | table.indexed_items             |
|----------------|    |---------------------------------|
| ID | SET       |    | ID | setId | itemId | have      |    
|----|-----------|    |----|-------|--------|-----------|
| 1  | set name 1|    | 1  | 3     | 1      | 2         |
| 2  | set name 2|    | 2  | 3     | 2      | 1         |
| 3  | set name 3|    | 3  | 3     | 3      | 4         |
                      | 4  | 2     | 4      | 1         |
                      | 5  | 2     | 5      | 3         |
                      | 6  | 2     | 6      | 1         |

我如何 return 在一个查询中,groupedBy/distinct 通过 setId(将名称设置为左连接?)得到这样的 return:

[
   setId: 2,
   name: 'set name 2',
   haveTotal: 5,
],
[
   setId: 3,
   name: 'set name 3',
   haveTotal: 7,
]

这是一个应该有效的原始 MySQL 查询。将其转换为 Laravel 应该不会太麻烦,尽管您可能需要使用 DB::raw 一次或两次。

SELECT
    s.ID AS setId,
    s.`SET` AS name,
    COALESCE(SUM(ii.have), 0) AS haveTotal
FROM sets s
LEFT JOIN indexed_items ii
    ON s.ID = ii.setId
GROUP BY
    s.ID;

Demo

如果您不想 return 集在 indexed_items table 中没有条目,那么您可以删除对 COALESCE 的调用,然后您可以还使用内部连接而不是左连接。

请注意,使用 SET 命名您的 table 和列不是一个好主意,因为它是一个 MySQL 关键字。

如果您正在使用或想使用 eloquent,您可以这样做:

$sets = App\Sets::withCount('indexed_items')->get();

这将 return 一个列名称为 indexed_items_count

的集合

显然,您需要根据您的型号名称进行更改。

Here are the docs

我经常在我的项目中使用计数关系记录。

$sets->indexed_items->count();