Предположим, что вы представляете эквивалент таблицы SQL, в Python, как список диктов, причем все дикты, имеющие одинаковые (предположим, строковые) ключи (другие представления, в том числе включенные numpy
, могут быть логически сведены к эквивалентная форма). Теперь внутреннее соединение является (опять же, с логической точки зрения) проекцией их декартового произведения - в общем случае, принимая аргумент предиката on
(который принимает два аргумента, одну «запись» [[dict]) ] из каждой таблицы и возвращает истинное значение, если две записи должны быть объединены), простой подход (использование префиксов для каждой таблицы для устранения неоднозначности против риска того, что две таблицы в противном случае могли бы иметь одноименные «поля»):
def inner_join(tab1, tab2, prefix1, prefix2, on):
for r1 in tab1:
for r2 in tab2:
if on(r1, r2):
row = dict((prefix1 + k1, v1) for k1, v1 in r1.items())
row.update((prefix2 + k2, v2) for k2, v2 in r2.items())
yield row
Теперь, конечно, вы не хотите, чтобы делал это таким образом, потому что производительность равна O(M * N)
- но, для указанной вами общности ("имитировать SQL-соединение выражением (внутренняя , external, full) ") альтернативы действительно нет, потому что предложение ON
для JOIN
довольно неограниченно.
Для внешних и полных объединений вам необходимо дополнительно хранить информацию, идентифицирующую, какие записи [[из одной или обеих таблиц]] еще не были получены, а в противном случае - например, для левого соединения вы бы добавили bool, сбросьте его до yielded = False
до внутреннего цикла for r2
, установите на True
, если выполняется yield
, и после внутреннего цикла if not yielded:
создайте искусственное соединение запись (предположительно, с использованием None
вместо NULL вместо пропущенных значений v2
, поскольку r2
фактически не используется для этой цели).
Чтобы получить какие-либо существенные улучшения эффективности, вам необходимо уточнить, какие ограничения вы хотите соблюдать в отношении предиката on
и таблиц - по вашему вопросу мы уже знаем, что вы не можете жить с unique
ограничение на ключи любой из таблиц, но есть много других ограничений, которые потенциально могут помочь, и заставить нас угадывать, что такие ограничения действительно применяются в вашем случае, было бы довольно непродуктивным усилием.