【问题标题】:How to get record for highest value based on type and 2 columns如何根据类型和 2 列获取最高值的记录
【发布时间】:2019-05-15 07:55:56
【问题描述】:

所以我在这里有一个名为 my_table 的表

| userid | gender | year | money |
| ------ | ------ | ---- | ----- |
| 1      | B      | 12   | 50    |
| 1      | B      | 24   | 150   |
| 1      | B      | 36   | 5     |
| 1      | G      | 0    | 0     |
| 1      | G      | 12   | 120   |
| 1      | G      | 48   | 120   |
| 2      | B      | 12   | 23    |
| 2      | B      | 24   | 56    |
| 2      | G      | 36   | 23    |
| 3      | G      | 0    | 234   |
| 3      | G      | 12   | 34    |
| 4      | G      | 0    |  0    |

我想根据性别返回最高可用金额的行。 因此,例如,性别 B 的返回表将是这样的

| userid | gender | year | money |
| ------ | ------ | ---- | ----- |
| 1      | B      | 24   | 150   |
| 2      | B      | 24   | 56    |

性别 G 的返回表会是这样的

| userid | gender | year | money |
| ------ | ------ | ---- | ----- |
| 1      | G      | 12   | 120   |
| 1      | G      | 48   | 120   |
| 2      | G      | 36   | 23    |
| 3      | G      | 0    | 234   |
| 4      | G      | 0    | 0     |

但是由于性别 G 的表重复了金钱的价值,我希望它返回最高年份的行。 性别 G 的预期表格是

| userid | gender | year | money |
| ------ | ------ | ---- | ----- |
| 1      | G      | 48   | 120   |
| 2      | G      | 36   | 23    |
| 3      | G      | 0    | 234   |
| 4      | G      | 0    | 0     |

我尝试过的:http://sqlfiddle.com/#!9/5433cbc/2 我能够获得性别 B 的表格,但不能获得性别 G 的表格。

我想要实现的是生成一个表格,将上面的两个性别表合并为一个。例如,

| userid | year_b | max_money_for_b | year_g | max_money_for_g |
| ------ | ------ | --------------- | ------ | --------------- |
| 1      | 24     | 150             | 48     | 120             |
| 2      | 24     | 56              | 36     | 23              |
| 3      | null   | null            | 0      | 234             |
| 4      | null   | null            | 0      | 0               |

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    我认为关联子查询是 MySQL 中最简单的方法:

    select t.*
    from my_table t
    where t.gender = 'G' and
          (t.year, t.money) = (select t2.year, t2.money
                               from my_table t2
                               where t2.userid = t.userid and
                                     t2.gender = t.gender
                               order by t2.money desc, t2.year desc
                               limit 1
                              );
    

    【讨论】:

    • 谢谢!这个解决方案更简单,更容易理解
    【解决方案2】:

    如下,我认为你会得到正确的结果。

    select
        m.userid,
        m.gender,
        tmp1.m_money as money,
        tmp2.m_year as year
    from
        my_table m
    join
    (
    select
        gender,
        userid,
        max(money) as m_money
    from
        my_table
    group by
        gender,
        userid
    ) tmp1 on m.gender = tmp1.gender and m.userid=tmp1.userid and m.money=tmp1.m_money
    join
    (
    select
        gender,
        userid,
        money,
        max(year) as m_year
    from
        my_table
    group by
        gender,
        userid,
        money
    ) tmp2 on m.gender = tmp2.gender and m.userid=tmp2.userid and m.money=tmp2.money and m.year=tmp2.m_year
    where m.gender='G'
    order by m.gender,m.userid
    

    如果你使用8.0以上的PostgreSQL或MySQL,事情会简单一些,你可以使用window函数来实现你的需求。如下:

    select * from 
    (
    select
        user_id,
        gender,
        money,
        year,
        row_number() over(partition by userid,gender order by money desc,year desc) as sort
    from
        my_table
    ) tmp where sort = 1
    

    【讨论】:

    • 我在哪里可以指定只有性别 G 或 B?您的查询返回性别和重复值。你可以在这里查看sqlfiddle.com/#!9/5433cbc/9 我也不能使用 row_number() 因为我的数据库没有更新。
    • 我已经修复了join错误,现在请看sqlfiddle.com/#!9/5433cbc/12,我认为它已经解决了你的问题,结果中没有重复的值。
    • 我更新了我的问题。希望你们能更好地理解
    • 所以您只想为每个 userId 在一行中显示 G 的值和 B 的值?
    • 是的,正确。我还没有实现你的查询。我回家后会试试的。由于您的查询能够为 G 表提取正确的值,所以我认为离开它们应该没问题
    【解决方案3】:

    从你的 where 条件中删除条件 gender = 'G'

    DEMO

    select t.* from my_table t where
    not exists (
        select 1 from my_table where userid = t.userid and money > t.money
            or (money = t.money and year > t.year)
        ) 
    

    【讨论】:

    • 我需要条件检查,因为我计划将性别 B 和 G 表加入另一个表,并将 2 列显示为 B_max_money、G_max_money、B_year 等
    猜你喜欢
    • 2021-12-10
    • 1970-01-01
    • 2021-05-18
    • 2019-07-02
    • 1970-01-01
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多