首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL -为每个标识符保留最新的非空值

MySQL -为每个标识符保留最新的非空值
EN

Stack Overflow用户
提问于 2018-08-21 23:49:21
回答 2查看 26关注 0票数 0

我想创建一个查询,其中包含每个玩家的最新信息。查询应该为每个玩家返回一个结果。如果玩家更改了他的gamertag,查询的结果应该返回玩家最近的非空gamertag。此行为应扩展到其他标识符,如城市、州和国家。以下是两个玩家的一些示例数据:

代码语言:javascript
复制
+-----------+-------------+-----------+--------+-----------+---------------+-------+
| player_id | recorded_at | gamertag  | prefix | city      | country       | state |
+-----------+-------------+-----------+--------+-----------+---------------+-------+
|     26640 |  1461421800 | Wobbaduck | NULL   | Toronto   | Canada        | ON    |
|     26640 |  1484931600 | Wobbaduck | NULL   | Saskatoon | Canada        | SK    |
|     26640 |  1510416000 | Mimic     | NULL   | NULL      | NULL          | NULL  |
|     26640 |  1516388400 | Mimic     | NULL   | NULL      | Canada        | SK    |
|     26640 |  1518278400 | Mimic     | NULL   | NULL      | NULL          | NULL  |
|      4507 |  1491678000 | The Moon  | NULL   | NULL      | NULL          | NULL  |
|      4507 |  1500645600 | The Moon  | MVG    | Buffalo   | United States | NY    |
|      4507 |  1533830400 | La Luna   | NULL   | New York  | United States | NY    |
+-----------+-------------+-----------+--------+-----------+---------------+-------+

查询应该会产生如下结果:

代码语言:javascript
复制
+-----------+----------+--------+-----------+---------------+-------+
| player_id | gamertag | prefix | city      | country       | state |
+-----------+----------+--------+-----------+---------------+-------+
|     26640 | Mimic    | NULL   | Saskatoon | Canada        | SK    |
|      4507 | La Luna  | MVG    | New York  | United States | NY    |
+-----------+----------+--------+-----------+---------------+-------+

字段recorded_at用于跟踪以纪元秒为单位的日期。我之前尝试过为每个标识符gamertagprefixcitycountrystate提供一个子查询和一个连接。如果可能的话,我想避免这样做。我使用的是MySQL 8.0.11。

我已经用示例数据创建了一个db-fiddle

EN

回答 2

Stack Overflow用户

发布于 2018-08-22 00:33:35

子查询有效地向下填充,外部查询挑选最后一个recorded_at

代码语言:javascript
复制
drop table if exists t;
create table t( player_id int,  recorded_at int, gamertag varchar(20),  prefix varchar(20), city varchar(20), country varchar(20)
, state varchar(20));
insert into t values
(    26640 ,  1461421800 , 'Wobbaduck' , NULL   , 'Toronto'   , 'Canada'        , 'ON') ,   
(    26640 ,  1484931600 , 'Wobbaduck' , NULL   , 'Saskatoon' , 'Canada'        , 'SK' ) ,  
(    26640 ,  1510416000 , 'Mimic'     , NULL   ,  NULL       , NULL            , NULL ) ,  
(    26640 ,  1516388400 , 'Mimic'     , NULL   ,  NULL       , 'Canada'        , 'SK' ) ,  
(    26640 ,  1518278400 , 'Mimic'     , NULL   ,  NULL       , NULL            , NULL ), 
(     4507 ,  1491678000 , 'The Moon'  , NULL   ,  NULL       , NULL            , NULL ), 
(     4507 ,  1500645600 , 'The Moon'  , 'MVG'  , 'Buffalo'   , 'United States' , 'NY' ),   
(     4507 ,  1533830400 , 'La Luna'   , NULL   , 'New York'  , 'United States' , 'NY' );

select * 
from
(
select t.player_id,t.recorded_at,

            if(t.gamertag is null,
            (select t1.gamertag from t t1 where t1.gamertag is not null and t1.player_id = t.player_id and t1.recorded_at < t.recorded_at order by t1.recorded_at desc limit 1),
            t.gamertag) gamertag, 

            if(t.prefix is null,
            (select t1.prefix from t t1 where t1.prefix is not null and t1.player_id = t.player_id and t1.recorded_at < t.recorded_at order by t1.recorded_at desc limit 1),
            t.prefix) prefix,

            if(t.city is null,
            (select t1.city from t t1 where t1.city is not null and t1.player_id = t.player_id and t1.recorded_at < t.recorded_at order by t1.recorded_at desc limit 1),
            t.city) city,

            if(t.country is null,
            (select t1.country from t t1 where t1.country is not null and t1.player_id = t.player_id and t1.recorded_at < t.recorded_at order by t1.recorded_at desc limit 1),
            t.country) country  

 from t
 order by t.player_id, t.recorded_at
 ) s
 where s.recorded_at = (select max(recorded_at) from t t1 where t1.player_id = s.player_id);   

+-----------+-------------+----------+--------+-----------+---------------+
| player_id | recorded_at | gamertag | prefix | city      | country       |
+-----------+-------------+----------+--------+-----------+---------------+
|     26640 |  1518278400 | Mimic    | NULL   | Saskatoon | Canada        |
|      4507 |  1533830400 | La Luna  | MVG    | New York  | United States |
+-----------+-------------+----------+--------+-----------+---------------+
2 rows in set (0.00 sec)
票数 0
EN

Stack Overflow用户

发布于 2018-08-22 04:23:25

这不完全是您想要的,但我认为它可以工作。对于列,它将获得每列的逗号分隔的值列表。您所要做的就是获取第一个值,它将是该列的最新值。

代码语言:javascript
复制
select *
from player a
JOIN (SELECT MAX(`recorded_at`) as `recorded_at`,
        `player_id`,
        GROUP_CONCAT(`gamertag` ORDER BY `recorded_at` DESC) as `gamertag`,
        GROUP_CONCAT(`prefix` ORDER BY `recorded_at` DESC) as `prefix`,
        GROUP_CONCAT(`city` ORDER BY `recorded_at` DESC) as `city`,
        GROUP_CONCAT(`country` ORDER BY `recorded_at` DESC) as `country`,
        GROUP_CONCAT(`state` ORDER BY `recorded_at` DESC) as `state`
      FROM `player`
      GROUP BY `player_id`) b
    ON a.`player_id` = b.`player_id`
        AND a.`recorded_at` = b.`recorded_at`;

SELECT *
FROM `ideal_player`;

查询#1

代码语言:javascript
复制
select *
from player a
JOIN (SELECT MAX(`recorded_at`) as `recorded_at`,
        `player_id`,
        GROUP_CONCAT(`gamertag` ORDER BY `recorded_at` DESC) as `gamertag`,
        GROUP_CONCAT(`prefix` ORDER BY `recorded_at` DESC) as `prefix`,
        GROUP_CONCAT(`city` ORDER BY `recorded_at` DESC) as `city`,
        GROUP_CONCAT(`country` ORDER BY `recorded_at` DESC) as `country`,
        GROUP_CONCAT(`state` ORDER BY `recorded_at` DESC) as `state`
      FROM `player`
      GROUP BY `player_id`) b
    ON a.`player_id` = b.`player_id`
        AND a.`recorded_at` = b.`recorded_at`;

| player_id | recorded_at | gamertag | prefix | city     | country       | state | recorded_at | player_id | gamertag                                    | prefix | city              | country                     | state    |
| --------- | ----------- | -------- | ------ | -------- | ------------- | ----- | ----------- | --------- | ------------------------------------------- | ------ | ----------------- | --------------------------- | -------- |
| 4507      | 1533830400  | La Luna  |        | New York | United States | NY    | 1533830400  | 4507      | La Luna,The Moon,The Moon                   | MVG    | New York,Buffalo  | United States,United States | NY,NY    |
| 26640     | 1518278400  | Mimic    |        |          |               |       | 1518278400  | 26640     | Mimic,Mimic,Mimic,Mimic,Wobbaduck,Wobbaduck |        | Saskatoon,Toronto | Canada,Canada,Canada        | SK,SK,ON |

View on DB Fiddle

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51952431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档