我有一个看起来像这样的表
id | title | value | language
---+-------+-------+---------
1 | a | 1800 | NULL
2 | a | 1900 | NULL
3 | b | 1700 | NULL
4 | b | 1750 | NULL
5 | b | 1790 | 1
6 | c | 1892 | NULL
7 | c | 1900 | 1
8 | c | 1910 | 2
9 | d | 3020 | NULL
想要得到以下结果:
id | title | value | language
---+-------+-------+---------
2 | a | 1900 | NULL
4 | b | 1750 | NULL
5 | b | 1790 | 1
6 | c | 1892 | NULL
7 | c | 1900 | 1
8 | c | 1910 | 2
9 | d | 3020 | NULL
重点是在每种标题的每种语言的“值”列中选择最大值-最大值是最新值。其次,当我使用MERGE算法构建MySQL View时,想避免诸如MAX,DISTINCT或GROUP-BY之类的聚合函数,并且不想最终创建一个临时表(请参见{{3}的底部) }。
到目前为止,此方法有效,但仅返回每个标题的最大行:
SELECT t1.title
FROM table t1
LEFT OUTER JOIN table t2
ON t1.title = t2.title
AND t1.value < t2.value
WHERE t2.title IS NULL
如何创建一种像上面的结果一样考虑语言的语言?谢谢。
答案 0 :(得分:1)
此答案假定您使用的是MySQL 8+,在其中查询变得非常容易。 MySQL 8和更高版本支持分析功能,这些功能是为了解决此类问题而添加的。
我们可以在此处尝试使用ROW_NUMBER
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY title, language ORDER BY value DESC) rn
FROM yourTable
)
SELECT id, title, value, language
FROM cte
WHERE rn = 1;
有一种方法可以使用MySQL的早期版本来解决此问题,但是它需要用户变量,并且往往很丑陋。因此,如果您希望有许多与此查询类似的查询,请考虑升级。
答案 1 :(得分:1)
这应该给您您想要的东西。
SELECT t1.title, t1.value, t1.language
FROM [Table] t1
LEFT OUTER JOIN [Table] t2 ON
t1.title = t2.title AND
(IFNULL(t1.language, '') = IFNULL(t2.language, ''))
WHERE
t1.value > t2.value;
答案 2 :(得分:1)
您可以使用NOT EXISTS
来做到这一点:
select t.*
from tablename t
where not exists (
select 1 from tablename
where
title = t.title and
coalesce(language, 0) = coalesce(t.language, 0) and
value > t.value
)
请参见demo。
结果:
| id | title | value | language |
| --- | ----- | ----- | -------- |
| 2 | a | 1900 | NULL |
| 4 | b | 1750 | NULL |
| 5 | b | 1790 | 1 |
| 6 | c | 1892 | NULL |
| 7 | c | 1900 | 1 |
| 8 | c | 1910 | 2 |
| 9 | d | 3020 | NULL |