Запрос MySQL для перекрестного выбора

#mysql

#mysql

Вопрос:

пакеты: package_id, user_id

транзакции: product_id,user_id,package_id

Я хочу выбрать строки в транзакциях, которые имеют package_id null или 0, но это возможно только тогда, когда есть другие транзакции с тем же user_id, где идентификатор пакета больше 0. Извините за плохой английский… Я попытался проверить это, но не смог угадать правильный вопрос для запроса Google.

Я знаю, что это название не подходит, поэтому, пожалуйста, кто-нибудь, предложите лучшее.

Gwynnbleid1

Комментарии:

1. Добро пожаловать в Stackoverflow. Где вы попали под удар? Дело в понимании запроса? Кроме того, вы должны показать нам, что вы уже сделали.

2. Я просто хотел бы, чтобы все знали о хорошем веб-сайте для таких вопросов, как этот (это средство для улучшения SQL с множеством опций): dpriver.com/pp/sqlformat.htm

Ответ №1:

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

 SELECT DISTINCT T.*
FROM   packages P
       LEFT JOIN transactions T
         ON P.user_id = T.user_id
       LEFT JOIN transactions T2
         ON T.user_id = T2.user_id
WHERE  ( T.package_id IS NULL
          OR T.package_id = 0 )
       AND T2.package_id > 0 
  

Комментарии:

1. Это дало мне именно то, что я хотел. Первый ответ также был в порядке, но я отмечу это как окончательный, поскольку предполагается, что этот подход более эффективен. Спасибо всем вам 🙂 Я всегда знал, что этот сайт — лучшее место для публикации вопроса, но это был первый раз, когда у меня самого возник вопрос.

Ответ №2:

Этот запрос выдаст вам все транзакции для package_id > 0 пользователей, у которых есть хотя бы одна другая транзакция с NULL или 0 package_id .

 SELECT * FROM transactions WHERE user_id IN 
(SELECT user_id FROM transactions WHERE package_id IS NULL OR package_id = 0) 
AND package_id > 0;
  

Комментарии:

1. Хотя это будет работать, особенно одноразово, использование IN не рекомендуется при больших наборах записей, это может действительно замедлить выполнение вашего запроса. Если вы собираетесь запускать этот запрос в приложении несколько раз, есть более эффективные способы.

2. @invertedSpear: Я определенно предпочитаю JOINs для производительности, но я подумал, что это проще понять.

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

4. вы правы, in (особенно в этом случае) намного проще для понимания, я поймал себя на том, что использую их чаще, чем следовало бы.

Ответ №3:

 SELECT A.* FROM

(SELECT * FROM TRANSACTIONS WHERE (package_id = 0 or package_id is null)) A
(SELECT * FROM TRANSACTIONS WHERE package_id is not null) B

WHERE A.userID = B.userID
  

Комментарии:

1. Этот запрос выдал мне ошибку: # 1064 — У вас ошибка в вашем синтаксисе SQL; проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса для использования рядом ‘(ВЫБЕРИТЕ * ИЗ транзакций, ГДЕ package_id не равен нулю) B, ГДЕ A’ в строке 4 Я не знаю почему…

2. Черт возьми, ошибка заключается в пропущенной запятой в строке 2 после package_id is null)) A