gpt4 book ai didi

MySQL/MariaDB/SQLite : DISTINCT CONCAT

转载 作者:行者123 更新时间:2023-11-29 10:19:55 25 4
gpt4 key购买 nike

这个问题不一定只是与 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 - 因为23有相同的tagable_idtagable_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 一起使用并替换 CONCAT 时函数 (tagable_id || '-' || tagable_type) as identifier - 看起来有效。

所以现阶段我是: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 最低的记录的点击次数高于其同级记录,则不会返回该同级记录。

最佳答案

您可以使用 DISTINCT 来获取不同的组合,但不能获取整行:

DB::table('tags')->distinct()->get(['tagable_id', 'tagable_type']);

您必须使用更复杂的查询:

$join = DB::table('tags')
->select('tagable_id', 'tagable_type')->selectRaw('MIN(hits) as hits')
->whereIn('name', $tags->toArray())
->groupBy('tagable_id', 'tagable_type');
$sql = '(' . $join->toSql() . ') as grouped';
$tags = DB::table('tags')
->join(DB::raw($sql), function($join) {
$join->on('tags.tagable_id', '=', 'grouped.tagable_id')
->on('tags.tagable_type', '=', 'grouped.tagable_type')
->on('tags.hits', '=', 'grouped.hits');
})->mergeBindings($join)
->whereIn('name', $tags->toArray())
->get();

保证每个唯一组合一条记录的解决方案:

$join = DB::table('tags')
->select('tagable_id', 'tagable_type')->selectRaw('MIN(hits) as hits')
->whereIn('name', $tags->toArray())
->groupBy('tagable_id', 'tagable_type');
$sql = '(' . $join->toSql() . ') as grouped';
$ids = DB::table('tags')
->selectRaw('MIN(id) as id')
->join(DB::raw($sql), function($join) {
$join->on('tags.tagable_id', '=', 'grouped.tagable_id')
->on('tags.tagable_type', '=', 'grouped.tagable_type')
->on('tags.hits', '=', 'grouped.hits');
})->mergeBindings($join)
->whereIn('name', $tags->toArray())
->groupBy('tags.tagable_id', 'tags.tagable_type')
->pluck('id');
$tags = DB::table('tags')->whereIn('id', $ids)->get();

关于MySQL/MariaDB/SQLite : DISTINCT CONCAT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49489612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com