#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