我很抱歉,但是我无法理解这一点(即使在搜索并尝试了一些方法之后也是如此)。我要做的就是联接两个表,然后对article_translations表中created_at降序的联接进行排序。但是,我需要唯一的条目。
我有两个表:
articles
--------
id
user_id
article_translations
--------
id
article_id (brings this table together with the other one)
locale
title
...
created_at
updated_at
执行mysql查询:
SELECT * from articles
JOIN article_translations as t on t.article_id = articles.id
ORDER BY t.created_at desc
我获得了带有相应相关条目的联接表。
articles.id t.article_id created_at
1 1 ''
1 1 ''
2 2 ''
当我尝试不删除重复项时,在本例中id为1的文章中,我得到了一个讨厌的错误:
SELECT列表的表达式#3不在GROUP BY子句中,并且包含未聚合的列'blog.t.id',该列在功能上不依赖于GROUP BY子句中的列;这与sql_mode = only_full_group_by
不兼容所需的结果将是:
articles.id t.article_id created_at
1 1 ''
2 2 ''
请帮忙...谢谢!
答案 0 :(得分:2)
获取唯一行的唯一方法是,您是否希望每个id
的最新(或最早?)日期,如果您group by a.id, t.article_id
并进行汇总,则可以这样做:
SELECT a.id, t.article_id, MAX(t.created_at) AS created_at
FROM articles AS a INNER JOIN article_translations AS t
ON t.article_id = a.id
GROUP BY a.id, t.article_id
ORDER BY MAX(t.created_at) DESC
如果要使用2个表的所有列,请首先使用article_translations
从NOT EXISTS
获取唯一行,然后加入articles
:
SELECT *
FROM articles AS a INNER JOIN (
SELECT t.*
FROM article_translations t
WHERE NOT EXISTS (
SELECT 1 FROM article_translations
WHERE article_id = t.article_id AND created_at > t.created_at
)
) AS t
ON t.article_id = a.id
ORDER BY t.created_at DESC
如果article_translations
中created_at
的行数最多为article_id
,而行数不超过1,则此方法有效。
对于MySql 8.0+,您可以使用ROW_NUMBER()
:
SELECT t.* FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY a.id ORDER BY t.created_at DESC) rn
FROM articles AS a INNER JOIN article_translations AS t
ON t.article_id = a.id
) AS t
WHERE t.rn = 1
答案 1 :(得分:0)
因为您确实希望所有列:
如果您尝试仅保留具有最新创建日期的文章翻译,那么假设创建日期对于给定文章的翻译而言是唯一的,一种方法是创建一个子查询,为每个article_translation.article_id
计算article_translation.created_at
列的最大值:
SELECT articles.*, t.* from articles
JOIN article_translations as t on t.article_id = articles.id
JOIN (
SELECT article_id, max(created_at) as created_at from article_translations
GROUP BY article_id
) a_t on t.article_id = a_t.article_id and t.created_at = a_t.created_at
ORDER BY t.created_at desc
如果创建日期不是唯一的,或者即使不是,那么这也应该起作用:
SELECT articles.*, t.* from articles
JOIN article_translations as t on t.article_id = articles.id
AND t.article_id = (
SELECT t2.article_id from article_translations t2
WHERE t2.article_id = t.article_id
ORDER BY created_date DESC
LIMIT 1
)
ORDER BY t.created_at DESC
答案 2 :(得分:0)
您几乎可以回答问题中的查询。您只需要添加“ distinct”关键字:
SELECT distinct * from articles
JOIN article_translations as t on t.article_id = articles.id
ORDER BY t.created_at desc`
答案 3 :(得分:0)
感谢forpas提供正确的答案。我基本上需要结合Laravel Eloquent模型和急切加载的查询。万一有人在乎,那就是现在的最终解决方案:
$articles = Article::join('article_translations as at', function ($join) {
$join->on('articles.id', '=', 'at.article_id');
})
->select('articles.id',
'articles.user_id',DB::raw('MAX(at.created_at) as created_at'))
->groupBy('at.article_id')
->orderBy('created_at', 'desc')
->with('translations')
->get();
纯SQL
SELECT at.article_id, MAX(at.created_at) as created_at FROM articles as a
INNER JOIN article_translations as at
ON a.id = at.article_id
GROUP BY at.article_id
ORDER BY MAX(created_at) desc