Как сделать запрос с произвольным порядком по параметру, используя массив? - PullRequest
1 голос
/ 29 марта 2019

У меня есть алгоритм, который выводит массив в определенном порядке. Пример:

arr = [0, 1, 21, 2, 22, 23, 24, 25, 3, 27, 35, 36, 28, 37, 38, 4, 29, 5, 34, 6, 7, 8, 9, 10, 11, 12] 

Массив будет отличаться в зависимости от ввода пользователя, поэтому приведенный выше пример - только одна из множества неопределенных возможностей; длиннее, короче или разные значения (все значения будут целыми числами). Поэтому я не смогу использовать case в своем запросе.

Я хочу создать запрос SQL-Server в моем views.py , чтобы отобразить все объекты в моей модели в этом точном порядке.

Вот мой "запрос" на данный момент, но, очевидно, он не работает.

test = QuoteAssemblies.objects.raw("""SELECT qmaQuoteAssemblyID,
                                             qmaPartID,
                                             qmaLevel,
                                             qmaPartShortDescription,
                                             qmaQuantityPerParent
                                      FROM QuoteAssemblies
                                      WHERE qmaQuoteAssemblyID IN arr
                                      ORDER BY qmaQuoteAssemblyID = arr""")

По сути, я хочу, чтобы запрос был упорядочен по qmaQuoteAssemblyID, если он находится в том же порядке массива (не ASC, DESC и т. Д.).

qmaQuoteAssemblyID = 0
qmaQuoteAssemblyID = 1
qmaQuoteAssemblyID = 21
qmaQuoteAssemblyID = 2
etc...

Существует аналогичный пример для MySQL Здесь . Мне просто нужно что-то подобное, но для MSSQL. Приветствия.

1 Ответ

2 голосов
/ 29 марта 2019

Если ваша версия SQL Server поддерживает запросы JSON (т.е. 2016+), вы можете использовать функцию openjson() для нумерации элементов вашего массива, а затем использовать это число для сортировки:

declare @Arr nvarchar(max) = '[0, 1, 21, 2, 22, 23, 24, 25, 3, 27, 35, 36, 28, 37, 38, 4, 29, 5, 34, 6, 7, 8, 9, 10, 11, 12]';

SELECT q.qmaQuoteAssemblyID,
  q.qmaPartID,
  q.qmaLevel,
  q.qmaPartShortDescription,
  q.qmaQuantityPerParent
FROM dbo.QuoteAssemblies q
  inner join openjson(@Arr) ar on ar.[value] = q.qmaQuoteAssemblyID
ORDER BY ar.[key];

Если вы не можете использовать JSON для этой задачи, вам нужно каким-то образом создать набор строк с правильно пронумерованными элементами массива и использовать его аналогичным образом. Есть много способов достичь этого, и это не обязательно должно быть сделано на стороне сервера. Например, вы можете создать в вашей базе данных пользовательский тип таблицы с двумя столбцами key-value и предоставить данные в качестве параметра для вашего запроса.

Другой подход заключается в предоставлении данных в форме XML, что-то вроде этого:

declare @Ax xml = N'<r>
  <i n="0" v="0" />
  <i n="1" v="1" />
  <i n="2" v="21" />
  ...
</r>';

SELECT q.qmaQuoteAssemblyID,
  q.qmaPartID,
  q.qmaLevel,
  q.qmaPartShortDescription,
  q.qmaQuantityPerParent
FROM dbo.QuoteAssemblies q
  inner join @Ax.nodes('/r/i') ar(c) on ar.c.value('./@v', 'int') = q.qmaQuoteAssemblyID
ORDER BY ar.c.value('./@n', 'int');

Тем не менее, нумерацию узлов XML лучше выполнять приложением, поскольку не существует эффективного способа сделать это на стороне базы данных. Это и производительность может быть несколько хуже по сравнению с вариантом 1.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...