› MySQL 5.5 Community Server
› MySQL 5.6 Community Server
› Percona Configuration Wizard
› XtraBackup 搭建主从复制
Great Sites on MySQL
› Percona
› MySQL Performance Blog
› Severalnines
推荐管理工具
› Sequel Pro
› phpMyAdmin
推荐书目
› MySQL Cookbook
MySQL 相关项目
› MariaDB
› Drizzle
参考文档
› http://mysql-python.sourceforge.net/MySQLdb.html
sytnishizuiai
V2EX  ›  MySQL

MySQL 求助, group by 城市行业后获取工资最低的一条数据

  •  
  •   sytnishizuiai · Sep 11, 2019 · 6517 views
    This topic created in 2617 days ago, the information mentioned may be changed or developed.

    例如字段有 id,city,business,money 4 个字段,我想要获取各个 city 下不同 business 下的最低 money 并得到 id,

    我试了好几种方法,每次获取的值都是 id 靠前的,即便使用 MIN ( money ),id 也是无法对应。

    34 replies  •  2019-09-12 11:01:07 +08:00
    Keppel
    Keppel
    Sep 11, 2019
    1
    你可以试试 having
    newtype0092
    newtype0092
    Sep 11, 2019
    2
    按理说 group by 操作后应该只使用 group by 的列,如果要用到其他列就应该在 group by 之前先排序。
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    3
    @Keppel having 只能操作 group by 内的列,所以用不了
    @newtype0092 这个看过别人写,我自己试过用复合 sql,先根据 money 排序,然后 group by,还是没用
    newtype0092
    newtype0092
    Sep 11, 2019
    4
    select * from (select * from T order by money) tmp group by city, business;
    大概这样
    newtype0092
    newtype0092
    Sep 11, 2019❤️1
    5
    @sytnishizuiai 我自己的数据这种写法是 ok 的,你那边没用的话有没有具体的 case 啊
    dengzhaohui
    dengzhaohui
    Sep 11, 2019❤️1
    6
    @newtype0092 MySQL5.7 优化掉了子查询内的 order by,大部分说加上 limit 或 distinct 就能强制排序,然鹅我试过并没有用 排序分组难搞
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    8
    @dengzhaohui 超级感谢,你一下子说中要害了,我去查了下果然好多人说(昨天关于这个问题查了好久),现在加上 limit 就可以了
    ayonel
    ayonel
    Sep 11, 2019❤️2
    9
    新建表:
    CREATE TABLE `demo` (
    `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
    `city` varchar(11) DEFAULT NULL,
    `business` varchar(11) DEFAULT NULL,
    `money` int(11) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    插入以下数据:
    id city business money
    1 beijing waimai 10
    2 beijing dache 20
    3 beijing dache 30
    4 beijing waimai 40
    5 beijing waimai 20

    按照楼主的意思,需要返回的结果是:id=3 以及 id=4 的记录


    思路:自己 left join 自己,将统一分组的记录 join 一起,并且加一个过滤条件 左表的 money < 右表的 moeny, 这样的结果是所有符合该条件的关联记录中,右表都会有值。最终只需要挑右表中任意字段为 null 的记录就行了。

    sql:
    select a.* from demo a left join demo b on a.city=b.city and a.business=b.business and a.money < b.money where b.money is null;

    结果:
    3 beijing dache 30
    4 beijing waimai 40
    xux9311
    xux9311
    Sep 11, 2019❤️1
    10
    要 group by 字段外的信息么,原来的表 join 一下吧
    大概这样
    ```sql
    select business.id, business.money from business join (select city, min(money) as min_money from business group by city) as temp on business.city = temp.city and business.money = temp.min_money;
    ```
    gz911122
    gz911122
    Sep 11, 2019
    12
    升 8.0
    然后用开窗函数

    换 pg
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    13
    @ayonel 谢谢,这个方法我看到过但没试,因为项目的表很大 本身就是 2 表关联查询,会变的更复杂就没考虑了。
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    14
    @xux9311 类似的方案我试过,里面那个 select group by 的时候,得到的 min(money)和 city 其实不是匹配的
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    15
    @ayonel 这个答案 5.7 不能用了,就是 4 楼的,现在加个 limit 就行
    jadec0der
    jadec0der
    Sep 11, 2019
    16
    先排序,再 group by,用了 ls 的表和数据

    http://www.sqlfiddle.com/#!9/4aaa7f/4
    newtype0092
    newtype0092
    Sep 11, 2019
    17
    @dengzhaohui 我的版本还是 5.6,用 5.7 试了一下,group by 语句里 select 其他字段直接报 ERROR 了。。。
    ayonel
    ayonel
    Sep 11, 2019
    18
    @sytnishizuiai 为什么不能用,我就用的 5.7
    ayonel
    ayonel
    Sep 11, 2019
    19
    @jadec0der 这种写法默认的 mysql 5.7 开启了 ONLY_FULL_GROUP_BY 参数,会报错。
    Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 't.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    20
    @gz911122 我去学习下

    @jadec0der 我 5.7 就不行了

    @ayonel 不好意思,我就看了第一个,第一个不行的 我试了好几遍,第二个答案和 9 楼的想法一样,学习了
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    21
    @ayonel only_full_group_by 肯定改了,你说的应该是链接内第一个答案,我 5.7.26 ,我试了 N 次了,因为我搜索到的大部分解决方案都是这个
    lolizeppelin
    lolizeppelin
    Sep 11, 2019 via Android
    22
    统计分析请换 pg 2333
    ayonel
    ayonel
    Sep 11, 2019
    23
    @sytnishizuiai 不明白这种写法为什么会报错,这符合标准 sql 规范。我 5.7.21
    dexterzzz
    dexterzzz
    Sep 11, 2019 via Android
    24
    window 函数,sql 基础技术
    1runningbird
    1runningbird
    Sep 11, 2019 via iPhone
    25
    自己 join 自己
    akira
    akira
    Sep 11, 2019
    26
    @sytnishizuiai 10l 的方案应该是可以出正确答案的,city 和 money 不匹配的话,应该是 bussiness 那边的影响。 用 9l 的表写出来大概这样

    select demo.id, a.* from demo ,
    (
    select city,business, min(money) `min_money` from demo
    group by city, business
    ) a

    where demo.city = a.city and demo.business = a.business and demo.money = a.min_money
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 11, 2019
    27
    @akira 我项目和帖子的 demo 我都试过,获得的结果,min(money)只是额外多一列最小值(加上或去掉,其他数据都没变化),所以 MIN 的值和同行其他字段是匹配不上的,所以会导致外面的 select 也没用了。
    akira
    akira
    Sep 11, 2019
    28
    @sytnishizuiai 你是不是漏了 group by。
    pmsg863
    pmsg863
    Sep 11, 2019
    29
    开窗函数了解下。
    hfc
    hfc
    Sep 11, 2019
    30
    mark
    前两天我也想做类似的处理,一直搞不定,后来直接改表结构了😂,来你这一看,原来是 5.7 之后没法那么用了...
    xux9311
    xux9311
    Sep 11, 2019
    31
    @sytnishizuiai min(money)和 city 在 group by city 的情况下怎么会不匹配呢。可能我理解错你的问题了,(city, business)是 unique index 吧?
    robert233
    robert233
    Sep 11, 2019
    32
    mysql 8.0 新增了窗口函数
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 12, 2019
    33
    @xux9311 我是 5.7 的,我在自己项目和帖子内的简易 demo (无索引)都试过,确实会出现匹配不上的情况
    sytnishizuiai
    sytnishizuiai
    OP
    Sep 12, 2019
    34
    @gz911122
    @dexterzzz
    @pmsg863
    @robert233 谢谢,学习了!
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1074 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 59ms · UTC 18:34 · PVG 02:34 · LAX 10:34 · JFK 13:34
    ♥ Do have faith in what you're doing.