Как получить строку из БД с условием - другая существует в другой таблице? - PullRequest
0 голосов
/ 26 июня 2019

У меня есть две таблицы notifications и archived_notifications.

Уведомления

id | title | caption | user_id

Архивные уведомления

notification_id | user_id

Как должен выглядеть запрос SQL, если я хочу получить строки из таблицы notifications, для которых в таблице archived_notifications нет строки, такой как notification_id = notification.id | user_id = notification.user_id.

Теперь у меня есть такие

cursor.execute("SELECT * FROM notifications AS n WHERE "
                   "({}=%s AND (SELECT COUNT(*) FROM archvies WHERE {}=n.id AND {}=%s) = 0) "
                   "OR "
                   "({}=%s AND (SELECT COUNT(*) FROM archvies WHERE {}=n.id AND {}=%s) = 0) "
                   "ORDER by id DESC LIMIT %s OFFSET %s"
                   .format(Keys.USER_ID, Keys.NOTIFICATION_ID, Keys.USER_ID, Keys.DIRECTION, Keys.NOTIFICATION_ID,
                           Keys.USER_ID),
                   [str(user_id), str(user_id), NotificationsClasses.GLOBAL, str(user_id), int(limit), int(offset)])

1 Ответ

1 голос
/ 26 июня 2019

Как правило, вы можете использовать любое из предложений NOT IN или NOT EXISTS против LEFT JOIN . В частности, у вас, похоже, есть ряд других неясных условий, таких как обработка direction и форматирование строк имен столбцов из неизвестных Keys переменных.

Ниже показана опция NOT EXISTS с попыткой перевода вашего текущего кода. Отрегулируйте к фактическим потребностям:

sql = '''SELECT * FROM notifications AS n 
         WHERE n.user_id = %s
           AND NOT EXISTS
              (SELECT 1 FROM archives a
               WHERE a.user_id = %s
                 AND n.id = a.notification_id)
         ORDER by n.id DESC 
         LIMIT %s 
         OFFSET %s
      '''

cursor.execute(sql, [str(user_id), NotificationsClasses.GLOBAL, int(limit), int(offset)])
...