【发布时间】:2019-08-01 21:56:39
【问题描述】:
我试图帮助解决这个问题Selecting rows based on a few rules
这个想法是为每个用户选择与@lenguage 匹配的语言的行 ID,否则选择创建的第一种语言。
因为没有row_number(),不得不使用用户变量。考虑我添加一个字段test_id,这样可以将所有案例放在同一张桌子上。
SELECT t.* , (`language` = @language) as tt,
@rn := if (@partition = CONCAT(`test_id`, '-', `user`),
@rn + 1,
if(@partition := CONCAT(`test_id`, '-', `user`), 1, 1)
) as rn,
@partition
FROM Table1 t
CROSS JOIN ( SELECT @language := 'de', @rn := 0, @partition := '' ) as var
ORDER BY CONCAT(`test_id`, '-', `user`),
(`language` = @language) DESC,
`created`
输出
但即使ORDER BY 给出了正确的排序,分区1-4 和3-4 也不会将语言'de' 放在首位。所以有些东西正在改变变量@rn 的分配方式。
| test_id | id | title | language | created | user | tt | rn | @partition |
|---------|----|-------|----------|----------------------|------|----|----|------------|
| 1 | 3 | c | de | 2019-01-03T00:00:00Z | 4 | 1 | 3*| 1-4 |
| 1 | 1 | a | en | 2019-01-01T00:00:00Z | 4 | 0 | 1 | 1-4 |
| 1 | 2 | b | es | 2019-01-02T00:00:00Z | 4 | 0 | 2 | 1-4 |
| 2 | 1 | a | en | 2019-01-01T00:00:00Z | 4 | 0 | 1 | 2-4 |
| 2 | 2 | b | es | 2019-01-02T00:00:00Z | 4 | 0 | 2 | 2-4 |
| 3 | 1 | a | en | 2019-01-01T00:00:00Z | 3 | 0 | 1 | 3-3 |
| 3 | 3 | b | de | 2019-01-03T00:00:00Z | 4 | 1 | 2*| 3-4 |
| 3 | 2 | b | es | 2019-01-02T00:00:00Z | 4 | 0 | 1 | 3-4 |
| 3 | 4 | c | de | 2019-01-04T00:00:00Z | 5 | 1 | 1 | 3-5 |
【问题讨论】:
-
MySQL 手册说了一些关于 “涉及用户变量的表达式的评估顺序未定义。” 很确定这发生在这里.. @Barmar 的建议接缝是正确的..
-
@Barmar 我为调试添加了 tt,我在
order by中有(language = @language) DESC。除非您的意思是我必须先创建一个子查询才能在执行@rn 之前进行排序? -
你期望的完整输出是什么,你应该期待
de在组中的第一个吗? -
是的@RaymondNijland 这就是为什么我使用
if()来确保应用正确的顺序。变量只在if()内改变 -
@RaymondNijland for partition
1-4我希望“de”是 1,然后是 2,3。顺序正确,但变量应该是1,2,3而不是3,1,2
标签: mysql sql user-variables