mysql - Django 1.6 + MySQL : Type Cast MySQL variable to search for Max, 平均

标签 mysql django django-orm django-aggregation

我的模型有点像

class ServiceUtilization(models.Model):
device_name = models.CharField()
service_name = models.CharField()
data_source = models.CharField()
current_value = models.CharField()
sys_timestamp = models.IntegerField()

现在,这里current_value表示存储为 VarChar 的 Float 中的值,w.r.t 时间存储为 unixtime

在尝试获取 current_value 的最大值和平均值时我得到了意想不到的结果,因为对于 Max,MySQL 会进行基于字符串的比较,在 '100' value < '9.99' 中在 Float 中采用了不正确的 w.r.t 值。

我试过了:

perf = ServiceUtilization.objects.filter(
        device_name__in=devices,
        service_name__in=services,
        data_source__in=data_sources,
        sys_timestamp__gte=start_date,
        sys_timestamp__lte=end_date
    ).values(
        'device_name',
        'service_name',
        'data_source'
    ).annotate(
        max_val=Max('current_value'),
        avg_val=Avg('current_value')
    )

它提供了不正确的结果。

然后查看:HOW select min from cast varchar to int in mysql

我考虑过使用 extra 提供查询集

perf = ServiceUtilization.objects.extra(
       select={
          'max_val': "MAX(CAST(current_value AS SIGNED))",
          'avg_val': "AVG(CAST(current_value AS SIGNED))"
       }
       ).filter(
        device_name__in=devices,
        service_name__in=services,
        data_source__in=data_sources,
        sys_timestamp__gte=start_date,
        sys_timestamp__lte=end_date
    ).values(
        'device_name',
        'service_name',
        'data_source',
        'max_val',
        'avg_val'
    )

但这只是提供了一个单一的值(value),而不是想要的结果。这将转换为 SQL

SELECT (MAX(CAST(current_value AS SIGNED))) AS `max_val`, (AVG(CAST(current_value AS SIGNED))) AS `avg_val`, `performance_utilizationstatus`.`device_name`, `performance_utilizationstatus`.`service_name`, `performance_utilizationstatus`.`data_source`

来自 performance_utilizationstatus订购 performance_utilizationstatus . sys_timestamp描述;

但工作代码需要对 (device_name, service_name, data_source) 进行 GROUP BY

SELECT (MAX(CAST(current_value AS SIGNED))) AS `max_val`, (AVG(CAST(current_value AS SIGNED))) AS `avg_val`, `performance_utilizationstatus`.`device_name`, `performance_utilizationstatus`.`service_name`, `performance_utilizationstatus`.`data_source`  FROM `performance_utilizationstatus` 

分组依据 performance_utilizationstatus . device_name , performance_utilizationstatus . service_name , performance_utilizationstatus . data_source 订购 performance_utilizationstatus . sys_timestamp描述;

如何添加 GROUP BY CLAUSE ?

使用 annotate不会在这里工作

1111, 'Invalid use of group function'

ERROR 1056 (42000): Can't group on 'max_val'

RAW SQL 是最后的选择吗?

最佳答案

我认为您必须使用 .raw,因为在这里不可能使用 .extra

问题是因为 Django 没有 .group_by 唯一的方法是使用 .values >.annotate 之后。 (正如您在第一次尝试中所做的那样)

所以.. 为什么你不能使用 .extra ?因为:

Any extra() call made after a values() call will have its extra selected fields ignored.

If you use a values() clause after an extra() call, any fields defined by a select argument in the extra() must be explicitly included in the values() call.

所以获取 .extra 字段的唯一方法是将它们添加到 .values 中,但这将导致按此字段分组,这是一种不受欢迎的行为。

关于mysql - Django 1.6 + MySQL : Type Cast MySQL variable to search for Max, 平均,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29052648/

相关文章:

python - Heroku - Django : Had to change every mentioning of `myproject` into `app` to get my site working. 将来如何最好地避免这种情况?

Django ORM : Perform conditional `order_by`

php - sql中缺少参数

php - $_GET 和 table.php?ini=ABC

django auto slug 在模型形式中,如 django admin 中的预填充字段

python - 如何避免围绕 Django 自定义数据库函数调用的 SQL 中的括号?

php - 错误 : fetching data from mysql and showing in on the web

mysql - Azure SQL,触发之前?

django - Django 用户模型中的多个 USERNAME_FIELD