代码之家  ›  专栏  ›  技术社区  ›  MHF

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

  •  7
  • MHF  · 技术社区  · 7 年前

    用户 :
    用户名-用户名-电话

    :

    我有如下记录:

    user_id: 23  
    meta_key: gender  
    meta_value: male  
    meta_date: 1534533650
    
    
    
    user_id: 23  
    meta_key: city  
    meta_value: london  
    meta_date: 1534533650
    
    
    
    user_id: 23  
    meta_key: name  
    meta_value: jack  
    meta_date: 1534533650  
    
    
    
    user_id: 25  
    meta_key: name  
    meta_value: Jamie 
    meta_date: 1534593881  
    
    user_id: 25  
    meta_key: gender  
    meta_value: male 
    meta_date: 1534593881  
    
    user_id: 23  
    meta_key: gender  
    meta_value: female  
    meta_date: 1534595971
    
    user_id: 23  
    meta_key: city  
    meta_value: liverpool  
    meta_date: 1534595971 
    
    And ...
    

    我需要用 最新的

    user_id: 23  
    meta_key: name  
    meta_value: Jamie  
    meta_date: 1534533650 
    
    user_id: 23  
    meta_key: city  
    meta_value: liverpool  
    meta_date: 1534595971  
    
    user_id: 23  
    meta_key: gender  
    meta_value: female  
    meta_date: 1534595971  
    

    这个操作的查询很复杂,我很困惑,请帮助我,

        "SELECT kmu.*
                FROM user_meta kmu
                INNER JOIN
                (SELECT `meta_key`, `meta_value`, MAX(`meta_date`) AS MaxDateTime
                FROM user_meta
                GROUP BY meta_key) groupedtt
                ON user_id=:id
                AND kmu.meta_key = groupedtt.meta_key
                AND kmu.meta_date = groupedtt.MaxDateTime";
    
    3 回复  |  直到 7 年前
        1
  •  5
  •   Sebastian Brosch Navjyot    7 年前

    您可以使用以下选项:

    SELECT `user`.*, user_meta.meta_key, user_meta.meta_value, user_meta.meta_date 
    FROM `user` INNER JOIN (
        SELECT user_id, meta_key, MAX(meta_date) AS meta_date 
        FROM user_meta 
        GROUP BY user_id, meta_key
    ) meta_select ON `user`.user_id = meta_select.user_id 
    INNER JOIN user_meta ON meta_select.meta_key = user_meta.meta_key 
        AND meta_select.user_id = user_meta.user_id 
        AND meta_select.meta_date = user_meta.meta_date
    WHERE `user`.user_id = 23
    

    https://www.db-fiddle.com/f/euqvGNW6PguCG495Yi9dTa/1

        2
  •  5
  •   Harly Hallikas    7 年前

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

    SELECT 
      user.*, meta.meta_key, meta.meta_value, meta.meta_date FROM user 
    LEFT JOIN 
      (
        SELECT * FROM 
          (SELECT * FROM user_meta WHERE user_id = 23 ORDER BY meta_date DESC) sub 
        GROUP BY 
          sub.meta_key
      ) meta 
    ON 
      user.user_id = meta.user_id
    ORDER BY 
      meta.meta_key;
    

    为了便于阅读,我将查询格式化成这样。您可能会看到我正在使用两个嵌套的子查询。这一要求来自这样一个事实:当您使用GROUPBY子句时,ORDERBY没有任何效果。因此,首先我们选择行并按日期描述排序,然后我们分组。这样它就保留了排序顺序。

    请看工作方案 here

        3
  •  0
  •   Andrei Odegov    7 年前

    我想提出一个基于 ROW_NUMBER 功能。这种解决方案在其他数据库中得到了广泛的应用。例如,看看 here . 但是你的MySQL版本不支持行数函数,我使用了它的仿真描述 here . 要检查我的解决方案,请单击 here

    SELECT
      *
    FROM `user` AS u
    LEFT JOIN (
      SELECT
        t.*
      FROM (
        SELECT
          @rn := IF(@uid = user_id AND @mk = meta_key, @rn + 1, 1) AS rn,
          @uid := user_id AS uid,
          @mk := meta_key AS mk,
          um.*
        FROM `user_meta` AS um
        CROSS JOIN (SELECT @uid := 0, @mk := 0, @rn := 0) AS i
        ORDER BY um.user_id, um.meta_key, um.meta_date DESC
      ) AS t
      WHERE t.rn = 1
    ) AS r ON u.user_id = r.user_id
    WHERE u.user_id = 23