Есть ли способ перебрать алфавит в kdb?
Я пишу функцию для выбора всех символов из базы данных, которые начинаются с буквы "A", затем "B", вплоть до буквы "Z". У меня есть фиктивная таблица с 3 символами, которая выглядит следующим образом...
t:([]symbol:`A`App`B`Bapp`C`Capp; price:104.3 124.3 134.2 103.4 402.7 209.8; ID:1 2 3 4 5 6)
наряду с функцией для выбора из таблицы, где символ выглядит как х...
fetch:{[x;y]select from x where symbol like y}
Затем я вызываю функцию для каждого алфавита и добавляю в новую таблицу...
fetchedA:h (`fetch; `t; "A*")
fetchedB:h (`fetch; `t; "B*")
fetchedC:h (`fetch; `t; "C*")
Новая пустая таблица вместе с функцией upsert...
newNormData:([]symbol:`$(); price:`float$(); ID:`int$())
newNorm:{[x] `newNormData upsert x}
h (`newNorm; fetchedA)
h (`newNorm; fetchedB)
h (`newNorm; fetchedC)
Вместо того, чтобы делать 26 вызовов функций для каждого сервера, я хотел бы сделать 1 вызов, который перебирает все символы в алфавите. Как правильно сделать это в kdb/q?
2 ответа
Переменная.Qa предоставляет список маленьких символов, а.QA - список заглавных символов. Вы можете использовать их для итерации. Есть несколько способов сделать это:
Простая итерация по персонажам и вызов каждого из них. Менее эффективно, поскольку это делает много вызовов RPC.
q) fetchAll: raze{h (`fetch; `t;x}) each .Q.A,'"*"
Более эффективный, поскольку он делает только 1 вызов RPC. Использование функции "лайк" для альтернативного выбора в шаблоне. Например, ниже команда выберет символы, начинающиеся с A или B.
Пример: выберите из таблицы, где символ как "[A|B]*"
Ниже команда рассмотрит все символы.
q) h(`fetch; `t;"[",("|" sv enlist each .Q.A),"]*")
Также, если ваши таблицы и функции находятся на одном сервере, вам не нужны разные вызовы rpc, чтобы сначала получить данные символов, а затем обновить таблицу newNorm. Вы можете сделать это за один звонок. Один из способов - определить функцию на сервере и вызвать ее.
Функция на сервере:
q) fetchAndUpdNorm:{[x]`newNormData upsert fetch[t] x}
На клиенте:
q) h(`fetchAndUpdNorm;"[",("|" sv enlist each .Q.A),"]*")
Обновление на основе комментариев Джонатона:
Альтернативная команда для второго примера:
q) h(`fetch; `t;"[A-Z]*")
Для последнего случая:
q) h(`fetchAndUpdNorm;"[A-Z]*")
Я верю, что вы ищете fetch[t] each .Q.A,'"*"
, Вы можете сделать это и перейти к новой таблице, запустив
h({`newNormData upsert fetch[`t] x;}';.Q.A,'"*")
сторона клиента.
В качестве альтернативы, если вы хотите использовать символы, начинающиеся только с заглавной буквы, и располагать их в алфавитном порядке, выполнить их проще.
newNormData:`symbol xasc select from t where symbol like "[A-Z]*"
вместо.