Django跟某几个字段去重MySQL

8 篇文章 0 订阅
5 篇文章 0 订阅

当我们需要查询一个数据表中的数据时,有时候会出现重复的情况。为了去除这些重复的数据,我们可以使用 SQL 的 DISTINCT 关键字来实现去重操作。在 Django 中,官方文档提供了 distinct 方法用于去重,但是只支持 PostgreSQL 数据库,具体操作可以看官方文档。那么对于使用 MySQL 数据库的用户,应该怎么办呢?在这篇博客中,我将为大家介绍一些实现 MySQL 去重查询的方法。

  • 首先,我们需要创建一个示例数据表 Book,用于演示去重查询的操作。代码如下:
from django.db import models

class Book(models.Model):
    book_name = models.CharField(max_length=256, verbose_name='名称')
    category = models.CharField(max_length=256, verbose_name='类型')
    price = models.IntegerField(verbose_name="价格")
  • 在这个示例数据表中,有三个字段:book_name 表示书籍名称,category 表示书籍类型,price 表示书籍价格。

  • 接下来,我们将介绍两种实现 MySQL 去重查询的方法。

方法一:使用 extra 方法

  • 使用 Django 的 extra 方法来在 SQL 查询语句中添加自定义的条件。代码如下:
queryset = Book.objects.extra(where=[
    'book.id in (SELECT id FROM book WHERE category=%s GROUP BY price, book_name)',
], params=["Python"])
  • 在这个示例代码中,首先调用 extra 方法,向查询语句中添加了一个自定义的条件。where 参数用于指定查询条件,在其中使用了子查询,查询出满足条件的 id 列表。
  • 在子查询中,对 pricebook_name 这两个字段进行了分组,并选取其中的一个 id。通过这种方式,就可以实现对 categoryPython 的数据进行去重操作了。

方法二:使用 raw 方法

我们也可以使用 Django 的 raw 方法,直接执行 SQL 查询语句,来实现去重查询的操作。代码如下:

queryset = Book.objects.filter(
    id__in=[i.id for i in Book.objects.raw(
        "SELECT * FROM book where category=%s GROUP BY price, book_name",
        ["Python"]
    )]
)

也可以把代码分解为下面几个步骤:

  1. 使用 raw 方法执行 SQL 查询,查询结果为一个元素为 Book 对象的列表,其中每个 Book 对象都包含了 pricebook_name 两个字段。
    result = Book.objects.raw("SELECT * FROM book WHERE category=%s GROUP BY price, book_name", ["Python"])
    
  2. 将查询结果转换为一个包含 id 字段的列表,用于后续过滤查询。
    id_list = [book.id for book in result]
    
  3. 使用 filter 方法对 Book 表进行过滤,其中 id__in 参数表示查询结果的 id 字段在指定列表中。
    queryset = Book.objects.filter(id__in=id_list)
    

其他

  • 其实下面这一句查询条件就足够查到需要的数据,但是使用raw查出来的并不是一个QuerySet对象,想要继续在queryset的基础上继续查询,就需要再进行一次转换。
    queryset = Book.objects.raw("SELECT * FROM book where category=%s GROUP BY price, book_name", ["Python"])
    

需要注意的是,在使用 rawextra 方法时,需要注意安全性问题,避免 SQL 注入攻击。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光不写代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值