私のモデルは一種の
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 の値を表し、unixtime として格納された時刻について
の最大値と平均値を取得しようとしているcurrent_value
ときに、予期しない結果が得られます。これは、Max の場合、MySQL が文字列ベースの比較を行うため、'100' value < '9.99'
誤った wrt 値が Float で取得されるためです。
私は試した :
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')
)
間違った結果を提供します。
次に見てください:mysqlでキャストvarcharからintに最小値を選択する方法
クエリセットを提供することを考えました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'
)
しかし、これは単一の値を提供するだけであり、望ましい結果ではありません。これは、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
DESC;
ただし、作業コードでは、(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
DESC;
GROUP BY CLAUSE を追加する方法は?
ここでは使用annotate
できません
1111, 'Invalid use of group function'
また
ERROR 1056 (42000): Can't group on 'max_val'
RAW SQL は最後の手段でしょうか?