我有一张这样的表:
id | subscriber_id | var_name | var_value | created
1 | 35 | last_name | Smith | [TIMESTAMP]
2 | 35 | city | New York | [TIMESTAMP]
3 | 35 | city | Boston | [TIMESTAMP]
在这种情况下,假设var_value=Boston
的行时间戳晚于var_value=New York
行,因此我们将选择Boston
行。
我尝试过这样的事情,但有时会说非聚合列分组。
SELECT
var_name, var_value
FROM
subscriber_vars
WHERE
subscriber = ?
GROUP BY subscriber
ORDER BY
created DESC
所以在这种情况下,预期的输出是:
[
'last_name' => 'Smith'
'city' => 'Boston'
]
答案 0 :(得分:2)
GROUP BY
SELECT * FROM (
SELECT var_name, var_value FROM subscriber_vars ORDER BY created DESC
) x
GROUP BY var_name
GROUP BY
将仅选择给定结果集中第一个唯一值的值,其顺序与结果行的顺序相同。
因此,我们运行一个查询来获取和排序我们想要的信息(SELECT var_name, var_value FROM subscriber_vars ORDER BY created DESC
),然后对查询返回的结果运行GROUP BY
。
现在,我们按照我们想要的顺序为我们提供了一组行,其中包含我们想要的列,其中只包含第一次出现的var_name
值。
现在,我们只需要SELECT
所有这些行返回它们,这就是SELECT * FROM
部分的用途。
请查看此StackOverflow post以进一步阅读。
答案 1 :(得分:-1)
如果您对以这种方式存储的数据量相当受限,并且列已正确编入索引,则以下查询应该有效:
select l.`last_name`, c.`city` from
(SELECT subscriber_id, var_value as `city` FROM subscriber_vars WHERE var_name='city' ORDER BY created DESC LIMIT 1) c
join
(SELECT subscriber_id, var_value as `last_name` FROM subscriber_vars WHERE var_name='last_name' ORDER BY created DESC LIMIT 1) l USING(subscriber_id)
where c.subscriber_id = 35;
返回的数据应如下所示:
last_name |city
Smith |Boston