【发布时间】:2018-09-04 11:43:49
【问题描述】:
这个问题不一定只是与 Laravel 相关,但我正在尝试获取记录,这些记录因连接字段而异。出于测试目的,我需要它与 MySQL/MariaDB 和 SQLite 一起使用。
在进行研究时,我发现 SQLite 没有 CONCAT 函数 - 相反,您使用 || 运算符来连接项目。另一方面,MySQL 不会以相同的方式解释 ||,但我总是可以使用条件语句来涵盖这两种情况。
但是,我仍然无法获得我想要的记录 - 我的表格包括:
| id | tagable_id | tagable_type | name | title | description | url | image | hits |
| 1 | 1 | App\Models\Article | a.. | A.. | A.. descr.. | https://localhost | https://localhost... | 0 |
| 2 | 1 | App\Models\Article | b.. | B.. | B.. descr.. | https://localhost | https://localhost... | 2 |
| 3 | 1 | App\Models\Article | c.. | C.. | C.. descr.. | https://localhost | https://localhost... | 3 |
| 4 | 1 | App\Models\Page | a.. | A.. | C.. descr.. | https://localhost | https://localhost... | 0 |
我只需要获得 4 条按命中次数按 ASC 排序且使用 CONCAT(table_id, tagable_type) 唯一的记录。
在这种情况下,语句应该返回 id 为 1 和 4 的记录 - 因为 2 和 3 具有相同的 tagable_id 和 tagable_type 与 id 为 1 的记录,命中次数最少 - 实际上只返回 2 条记录:
| id | tagable_id | tagable_type | name | title | description | url | image | hits |
| 1 | 1 | App\Models\Article | a.. | A.. | A.. descr.. | https://localhost | https://localhost... | 0 |
| 4 | 1 | App\Models\Page | a.. | A.. | C.. descr.. | https://localhost | https://localhost... | 0 |
我已经试过了:
DB::table('tags')
->selectRaw("DISTINCT CONCAT(`tagable_id`, '-', `tagable_type`), `id`, `name`, `title`, `description`, `url`, `image`")
->whereIn('name', $tags->toArray())
->orderBy('hits');
然而,这不会返回不同的记录 - 它会返回所有记录而不管不同的连接 - 在 MySQL / MariaDB 中 - 在 SQLite 中它会告诉我no such function: CONCAT。
我也试过了:
DB::table('tags')
->selectRaw("CONCAT(`tagable_id`, '-', `tagable_type`) as `identifier`, `id`, `name`, `title`, `description`, `url`, `image`")
->whereIn('name', $tags->toArray())
->groupBy('identifier')
->orderBy('hits');
这一次 MySQL/MariaDB 告诉我,我还需要在组中包含其他字段 tags.id' isn't in GROUP BY,但是当我将它与 SQLite 一起使用并用 (tagable_id || '-' || tagable_type) as identifier 替换 CONCAT 函数时 - 它似乎有效。
所以在这个阶段我是:MySQL: 0 | SQLite: 1
任何帮助将不胜感激。
更新
经过数小时的尝试解决后,我决定添加一个新列
identifier 到表中以克服不可用的concat 函数的问题 - 我的代码现在看起来像这样:
Tag::with('tagable')->whereIn('id', function($query) use ($tags) {
$query->selectRaw('min(`id`) from `tags`')
->whereIn('name', $tags->toArray())
->groupBy('identifier');
})
->orderBy('hits')
->take(4)
->get();
这仍然不是我所追求的,因为它依赖于给定标识符的最低 id min(id) 并且如果具有相同标识符的最低 id 的记录具有更高的命中数,则其兄弟姐妹然后兄弟姐妹不会被退回。
【问题讨论】:
-
更新您的问题添加适当的数据样本和预期结果
-
刚刚添加了示例数据和应返回内容的说明。
标签: mysql laravel laravel-5 sqlite