Упорядочить результат БД по определенному списку

#python-3.x #django-database

#python-3.x #django-база данных

Вопрос:

Мне нужно отобразить несколько строк (из запроса к БД) в соответствии с наибольшей встречаемостью одного конкретного поля. Кажется, что с чем-то подобным можно справиться с помощью SQL windowing, который я, к сожалению, не могу использовать.

Таким образом, я запрашиваю базу данных, чтобы подсчитать вхождение этого поля и упорядочить значение вхождения. Итак, я получаю список, который может выглядеть следующим образом:

 a = [504, 105, 494, 493, 439]
  

Второй результат, который должен быть упорядочен в соответствии с этим списком, выглядит следующим образом:

 b = [{'id': 3141, 'nr': 'T003745', 'storage': 'S000108', 'storage_id': 105}, 
{'id': 3140, 'nr': 'T003744', 'storage': 'S000108', 'storage_id': 105}, 
{'id': 3238, 'nr': 'T002720', 'storage': 'S001662', 'storage_id': 439}, 
{'id': 2091, 'nr': 'T002887', 'storage': 'S002268', 'storage_id': 493}, 
{'id': 2109, 'nr': 'T002924', 'storage': 'S002267', 'storage_id': 494}, 
{'id': 2103, 'nr': 'T002911', 'storage': 'S002267', 'storage_id': 494}, 
{'id': 2266, 'nr': 'T003012', 'storage': 'S002278', 'storage_id': 504}, 
{'id': 2267, 'nr': 'T002990', 'storage': 'S002278', 'storage_id': 504}, 
{'id': 2253, 'nr': 'T003066', 'storage': 'S002278', 'storage_id': 504}, 
{'id': 2258, 'nr': 'T003038', 'storage': 'S002278', 'storage_id': 504}]
  

Что мне нужно сейчас, так это упорядоченный список b в соответствии с последовательностью storage_id в a.

Результат должен выглядеть следующим образом:

 c = [{'id': 2266, 'nr': 'T003012', 'storage': 'S002278', 'storage_id': 504}, 
{'id': 2267, 'nr': 'T002990', 'storage': 'S002278', 'storage_id': 504}, 
{'id': 2253, 'nr': 'T003066', 'storage': 'S002278', 'storage_id': 504}, 
{'id': 2258, 'nr': 'T003038', 'storage': 'S002278', 'storage_id': 504},
{'id': 3141, 'nr': 'T003745', 'storage': 'S000108', 'storage_id': 105}, 
{'id': 3140, 'nr': 'T003744', 'storage': 'S000108', 'storage_id': 105},
{'id': 2109, 'nr': 'T002924', 'storage': 'S002267', 'storage_id': 494}, 
{'id': 2103, 'nr': 'T002911', 'storage': 'S002267', 'storage_id': 494},
{'id': 2091, 'nr': 'T002887', 'storage': 'S002268', 'storage_id': 493}, 
{'id': 3238, 'nr': 'T002720', 'storage': 'S001662', 'storage_id': 439}]
  

Ответ №1:

Тем временем я смог решить проблему, используя оконную функцию из PostgreSQL.

 Tool.objects.filter(tooltype_id__in=setupline
    .get_needed_toolytpe_ids())
    .filter(checked_in=True)
    .select_related('storage')
    .select_related('tooltype')
    .order_by('storage')
    .annotate(
        sum_tools=Window(expression=Count('id'),
        partition_by=F('storage_id'),)
    )
    .order_by('-sum_tools', Length('tooltype__name'))
  

Но я все же хотел бы знать, существует ли для этого умная и короткая функция без использования окон.