如何从user和usermeta表中选择最后一个用户信息?

hmtdttj4  于 2021-06-20  发布在  Mysql
关注(0)|答案(3)|浏览(335)

我正在使用mysql,我有两个表,格式如下:
用户:
用户名-用户名-电话
用户元:
user\u meta\u id-user\u id-meta\u key-meta\u value-meta\u date
我有如下记录:

  1. user_id: 23
  2. meta_key: gender
  3. meta_value: male
  4. meta_date: 1534533650
  5. user_id: 23
  6. meta_key: city
  7. meta_value: london
  8. meta_date: 1534533650
  9. user_id: 23
  10. meta_key: name
  11. meta_value: jack
  12. meta_date: 1534533650
  13. user_id: 25
  14. meta_key: name
  15. meta_value: Jamie
  16. meta_date: 1534593881
  17. user_id: 25
  18. meta_key: gender
  19. meta_value: male
  20. meta_date: 1534593881
  21. user_id: 23
  22. meta_key: gender
  23. meta_value: female
  24. meta_date: 1534595971
  25. user_id: 23
  26. meta_key: city
  27. meta_value: liverpool
  28. meta_date: 1534595971
  29. And ...

我需要获取所有注册了最新更改的用户信息(user\u id=23),例如:

  1. user_id: 23
  2. meta_key: name
  3. meta_value: Jamie
  4. meta_date: 1534533650
  5. user_id: 23
  6. meta_key: city
  7. meta_value: liverpool
  8. meta_date: 1534595971
  9. user_id: 23
  10. meta_key: gender
  11. meta_value: female
  12. meta_date: 1534595971

这个操作的查询很复杂,我很困惑,请帮帮我,
我使用了这个,但没有得到正确的结果:

  1. "SELECT kmu.*
  2. FROM user_meta kmu
  3. INNER JOIN
  4. (SELECT `meta_key`, `meta_value`, MAX(`meta_date`) AS MaxDateTime
  5. FROM user_meta
  6. GROUP BY meta_key) groupedtt
  7. ON user_id=:id
  8. AND kmu.meta_key = groupedtt.meta_key
  9. AND kmu.meta_date = groupedtt.MaxDateTime";
mxg2im7a

mxg2im7a1#

您可以使用以下选项:

  1. SELECT `user`.*, user_meta.meta_key, user_meta.meta_value, user_meta.meta_date
  2. FROM `user` INNER JOIN (
  3. SELECT user_id, meta_key, MAX(meta_date) AS meta_date
  4. FROM user_meta
  5. GROUP BY user_id, meta_key
  6. ) meta_select ON `user`.user_id = meta_select.user_id
  7. INNER JOIN user_meta ON meta_select.meta_key = user_meta.meta_key
  8. AND meta_select.user_id = user_meta.user_id
  9. AND meta_select.meta_date = user_meta.meta_date
  10. WHERE `user`.user_id = 23

demo:https://www.db-fiddle.com/f/euqvgnw6pgucg495yi9dta/1

eivgtgni

eivgtgni2#

我想提出一个基于行数函数的解决方案。该解决方案已广泛应用于其他数据库中。例如,看这里。但是您的mysql版本不支持row\u number函数,我使用了这里描述的模拟。要查看我的解决方案,请单击此处。

  1. SELECT
  2. *
  3. FROM `user` AS u
  4. LEFT JOIN (
  5. SELECT
  6. t.*
  7. FROM (
  8. SELECT
  9. @rn := IF(@uid = user_id AND @mk = meta_key, @rn + 1, 1) AS rn,
  10. @uid := user_id AS uid,
  11. @mk := meta_key AS mk,
  12. um.*
  13. FROM `user_meta` AS um
  14. CROSS JOIN (SELECT @uid := 0, @mk := 0, @rn := 0) AS i
  15. ORDER BY um.user_id, um.meta_key, um.meta_date DESC
  16. ) AS t
  17. WHERE t.rn = 1
  18. ) AS r ON u.user_id = r.user_id
  19. WHERE u.user_id = 23
展开查看全部
jvlzgdj9

jvlzgdj93#

虽然我强烈反对这种做法,但我不会改变你的想法。尽管有很多方法可以实现这一点,但我相信下面的查询的性能损失最小(不使用聚合)。

  1. SELECT
  2. user.*, meta.meta_key, meta.meta_value, meta.meta_date FROM user
  3. LEFT JOIN
  4. (
  5. SELECT * FROM
  6. (SELECT * FROM user_meta WHERE user_id = 23 ORDER BY meta_date DESC) sub
  7. GROUP BY
  8. sub.meta_key
  9. ) meta
  10. ON
  11. user.user_id = meta.user_id
  12. ORDER BY
  13. meta.meta_key;

为了便于阅读,我这样格式化了查询。您可能会看到我使用了两个嵌套的子查询。这个要求来自这样一个事实:当您使用GROUPBY子句时,ORDERBY不起作用。因此,我们首先选择行并按date desc排序,然后分组。这样它就保留了排序顺序。
请参阅这里的工作解决方案,还请注意,我在左窗格中的示例数据库创建脚本中添加了2个index create语句。随着数据库的增长,这些都是最低限度的,以确保至少有一些足够的性能。

展开查看全部

相关问题