MySQL查询去重,保留某个字段最大值的记录

本文详细介绍了一种SQL查询技巧,旨在根据子级的最新数据,逆向查询其父级的前五条相关记录。通过三步操作:首先,筛选所有符合条件的数据;其次,进行自链接查询以找到父级记录;最后,组装SQL语句并限制结果数量,确保查询高效准确。

目标:根据子级的最新数据来查询5条父级数据。


1、首先:查询出所有符合的相关数据。

SELECT Q.id , Q.pid FROM Q LEFT JOIN P ON P.id=Q.pid WHERE P.XXOO=... AND Q.XXOO...;

2、其次:自链接查询。

#SELECT A.* FROM A LEFT JOIN B ON A.XXOO = B.XXOO AND A.id < B.id WHERE B.id IS NULL;
SELECT A.* FROM A LEFT JOIN B ON A.XXOO = B.XXOO AND A.id < B.id WHERE B.id IS NULL ORDER BY A.id DESC LIMIT 5;

3、最后:组装sql查询。

    SELECT
        A.* 
    FROM
        (SELECT
            Q.id ,
            Q.pid 
        FROM
            Q 
        LEFT JOIN
            P 
                ON P.id=Q.pid 
        WHERE
            P.XXOO=... 
            AND Q.XXOO...) AS A 
    LEFT JOIN
        (
            SELECT
                Q.id ,
                Q.pid 
            FROM
                Q 
            LEFT JOIN
                P 
                    ON P.id=Q.pid 
            WHERE
                P.XXOO=... 
                AND Q.XXOO...
        ) AS B 
            ON A.XXOO = B.XXOO 
            AND A.id < B.id 
    WHERE
        B.id IS NULL 
    ORDER BY
        A.id DESC LIMIT 5;

 

在 SQL 查询中,根据某个字段有多种方法,以下为你详细介绍: ### 使用 `SELECT DISTINCT` `SELECT DISTINCT` 用于返回唯一不同的,基本语法如下: ```sql SELECT DISTINCT column_name FROM table_name; ``` 不过,这种语句在对某个字段时,无法保留其他字段的数据 [^1][^2]。 ### 使用窗口函数创建主键 当需要对数据中某个字段,并且保留其他字段的数据时,若表中没有主键,可以先使用窗口函数创建主键。例如用户对没有要求,字段复时保留任意一行,可在字段复时,选出对应主键大的那条数据作为保留数据,以此实现需求 [^2]。 ### 使用 `SELECT DISTINCT ON`(PostgreSQL) 在 PostgreSQL 中,`SELECT DISTINCT ON` 可以根据某个字段之后获取非聚合字段。语法如下: ```sql SELECT DISTINCT ON (column_name) * FROM table_name; ``` 例如: ```sql SELECT DISTINCT ON (age) * FROM t_user; ``` 在 MySQL 非严格模式下可以直接执行类似查询,但在严格模式和 PostgreSQL 里,不能直接查询非聚合列,而使用 `SELECT DISTINCT ON` 则可解决这个问题 [^3]。 ### 使用 `GROUP BY` 和聚合函数 可以结合 `GROUP BY` 和聚合函数(如 `MIN`、`MAX`)来实现。例如查询每个分组中 `id` 小的记录: ```sql SELECT * FROM tb_class WHERE id IN (SELECT min(id) FROM tb_class GROUP BY classname); ``` 也可以使用以下方式: ```sql SELECT * FROM tb_class WHERE classname IN (SELECT classname FROM tb_class GROUP BY classname HAVING COUNT(classname)>1) AND id NOT IN (SELECT min(id) FROM tb_class GROUP BY classname HAVING count(classname)>1); ``` 这里通过 `GROUP BY` 对 `classname` 分组,再利用 `HAVING` 筛选出有记录的分组,后排除每个分组中 `id` 小的记录 [^4]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值