Есть ли способ объединить несколько запросов и добавить столбец к данным, который представляет собой массив, из которого поступили данные? - PullRequest
1 голос
/ 30 марта 2020

Редактировать 1: До сих пор я тестировал следующую SQLAlchemy, но мне все еще нужно выяснить, как добавить к ней последний SELECT, который помещает данные в нужную форму. Есть идеи?

query1 = db.session.query(literal_column("'first_name'").label("matches"), models.User.id).filter(models.User.first_name == 'Joe')
query2 = db.session.query(literal_column("'last_name'").label("matches"), models.User.id).filter(models.User.last_name == 'Su')

union = db.union_all(query1, query2)
results = db.session.query(db.alias(union, name='users')).all()

Пожалуйста, прости меня, когда я пытаюсь объяснить это как можно лучше. Я ничего не пробовал, если кто-нибудь спросит. Я не нашел никакой информации, в которой бы прямо указывалось, можно ли это сделать или как это сделать.

Основной вопрос заключается в том, как я могу взять несколько небольших запросов к таблице и объединить их так, чтобы получающиеся данные имели столбец (с данные, которые он содержит, скорее всего, массив), который представляет собой список запросов, которые возвращали этот же объект.

Например, если у меня есть таблица с именем Users со следующими данными

id | first_name | last_name | age
1  |Joe         | Shmoe     | 39
2  |Marry       | Su        | 63
3  |Frank       | Su        | 39

и I иметь следующие запросы (для простоты используйте SQL, но это должно заканчиваться использованием кода стиля PostgreSQL ORM)

Select * from Users where first_name = "Joe"; 
 - resulting Ids: 1
Select * from Users where last_name = "Su";
 - resultings Ids: 2,3
Select * from Users where age ="39";
 - resulting Ids: 1,3

Запрос объединения должен заканчиваться на

id | first_name | last_name | age | matches
1  | Joe        | Shmoe     | 39  | ['first_name', 'age']
2  | Marry      | Su        | 63  | ['last_name']
3  | Frank      | Su        | 39  | ['last_name', 'age']

Если это возможно, как бы один go об этом?
Также к сведению. Я хотел бы иметь возможность специально обозначать, что входит в матчи. Например, я мог бы пометить первый запрос 'first_name', как в моем примере, или мог быть сделан 'firstName' или 'Dude', или что бы я ни пожелал.

Ответы [ 2 ]

2 голосов
/ 30 марта 2020

Это один из способов сделать это:

select id, first_name, last_name, age, array_agg(m) matches from (
    select 'first_name'::text m, * from users where first_name = 'Joe'
    union all
    select 'last_name'::text m, * from users where last_name = 'Su'
    union all
    select 'age'::text m, * from users where age ='39'
)   d 
group by id, first_name, last_name, age;

С уважением,
Bjarni

0 голосов
/ 30 марта 2020

Это то, что я в конце концов придумал. Не знаю, является ли это лучшим решением, но оно работает.

queries = []
queries.append(db.session.query(literal_column("'first_name'").label("m"), models.User.id.label('id')).filter(models.User.first_name == 'Joe'))
queries.append(db.session.query(literal_column("'last_name'").label("m"), models.User.id.label('id')).filter(models.User.last_name == 'Su'))


union = db.union_all(*queries)
alias = db.alias(union, name='users')

query_results = db.session.query(alias.c.id, func.array_agg(alias.c.m)).group_by('users.id').all()
results = []
for result in query_results:
    results.append({'id':result[0], 'matches': result[1]})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...