Используйте один запрос для извлечения из нескольких таблиц - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть пара запросов, которые, по моему мнению, могут быть реорганизованы и облегчены в mySQL, но я не уверен, как это сделать.Я делаю это программно, но я уверен, что я могу ускорить это.

По сути, получить идентификатор от пользователя, посмотреть в БД и получить идентификаторы строк, которые могут иметь похожие теги в качестве данного аргумента,чтобы исключить исходный аргумент и не включать повторяющиеся идентификаторы.

Есть ли способ сделать это в чистом sql?

вот мой текущий код:

def getRelatedEvents(self, memberId, eventId):
    relatated_events = []

    # first we get all the tags related to this event
    for tag in self.db.query("select tagName from event_tags where eventId={}".format(eventId)):
        # we iterate through each tag and find the eventIds for it
        events = self.db.query("SELECT eventId from event_tags where tagName LIKE %s and eventId != %s LIMIT 3",
                               '%'+tag['tagName']+'%', eventId)

    # we group them in a list, excluding ones that are already in here
        for id in events:
            if id['eventId'] not in relatated_events:
                relatated_events.append(id['eventId'])

    # we get the extra event info for each item in the related list and return
    return [self.getSpecificEvent(memberId, item) for item in relatated_events]

1 Ответ

0 голосов
/ 22 февраля 2019

Этого можно достичь с помощью самостоятельного объединения, например:

SELECT DISTINCT e2.eventId
FROM event_tags e1
INNER JOIN event_tags e2 
    ON e2.tagName LIKE CONCAT('%', e1.tagName, '%') AND e2.eventId != e1.eventId
WHERE e1.eventId = {}

Я заметил, что во втором запросе есть предложение LIMIT 3.Прежде всего, обратите внимание, что без условия ORDER BY это не приведет к предсказуемым результатам.Вот решение, основанное на оконной функции ROW_NUMBER() (доступной в MySQL 8), которая будет выдавать не более 3 event_id для каждого соответствующего тега:

SELECT DISTINCT event_id FROM (
    SELECT e2.eventId, ROW_NUMBER() OVER(PARTITION BY e1.eventId ORDER BY e2.eventId) rn
    FROM event_tags e1
    INNER JOIN event_tags e2 
        ON e2.tagName LIKE CONCAT('%', e1.tagName, '%') AND e2.eventId != e1.eventId
    WHERE e1.eventId = {}
) WHERE rn <= 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...