MySQL условный выбор - PullRequest
1 голос
/ 21 июля 2011

Я всю ночь пытался заставить работать следующий запрос:

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND if(24hr = 'yes') user.last_mail >= DATE_SUB (user.last_mail INTERVAL 1 DAY)

В основном у меня есть 3 таблицы, содержащие имя пользователя (wine_users), подписки (wine_subscriptions) и пользователяНастройки (user_settings)

Я ХОЧУ выбрать пользователей, которые ЛЮБОЙ выбрали НЕТ в течение 24 ч. ИЛИ выбрали ДА в течение 24 ч. (Сохраняется как ENUM «да», «нет» у нас.24 часа) И НЕ получал электронную почту в течение последних 24 часов (это сохраняется как TIMESTAMP в user.lastmail)

Любая помощь помешала бы мне вырвать мой собственный мозг через левую ноздрю!:)

Спасибо:)

Seb


Ух ты!Вы, ребята, великолепны!:) Перепробовал все предложения, но все они возвращают следующую ошибку:

1064 - у вас ошибка в синтаксисе SQL;проверьте руководство, соответствующее вашей версии сервера MySQL, на предмет правильного синтаксиса, который нужно использовать рядом с «ИНТЕРВАЛ 1 ДЕНЬ»))) LIMIT 0, 30 'в строке 8

Я предполагаю, что ему есть чем занятьсяс помощью команды DATE_SUB, которой не нравится формат TIMESTAMP поля user.last_mail ... Может ли это быть правильным, и если да, то как мне это сделать?

Для ясности сценарий является частью страницы, которая получаетУвольняемый Хроном каждый час, что я сделал для меня и нескольких друзей.
Он проверяет Tesco Wines на наличие их «таинственного винного пакета» (потому что веб-дизайн всегда лучше с дешевым вином!)
Еслион доступен (что происходит только раз в неделю или около того), он отправляет по электронной почте кому-либо из базы данных пользователей, у которого для ЛИБО 24 часа установлено значение «нет» (то есть он отправляет их по электронной почте каждый час, пока продукт доступен) ИЛИ для параметра «24 часа установлено значение ДА»и не получил письмо за последние 24 часа
(отсюда и поле last_mail, в котором записывается TIMESTAMP, когда было отправлено последнее письмо)

Действительно признателенответы!

Себ:)

Ответы [ 6 ]

0 голосов
/ 21 июля 2011

user.last_mail >= DATE_SUB (user.last_mail INTERVAL 1 DAY) никогда не может быть False!

Я думаю, вам нужно использовать функцию NOW() и некоторые скобки с OR:

SELECT user.username
     , user.email
     , user.id
     , user.last_mail
     , us.24hr
FROM wine_users AS user
    JOIN wine_subscriptions AS sub
        ON user.id = sub.user_id
    JOIN wine_user_settings AS us
        ON us.id = user.id
WHERE sub.wine1 = 'yes'
  AND user.receive_mail = 'yes'           --- not sure if this line is needed
                                          --- what does `receive_mail` stand for?
  AND ( user.24hr = 'no'
      OR user.last_mail < NOW() - INTERVAL 1 DAY
      OR user.last_mail IS NULL
      )
0 голосов
/ 21 июля 2011

Вы можете использовать OR:

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND (24hr = 'no' OR
     (24hr = 'yes' AND user.last_mail < DATE_SUB(NOW(), INTERVAL 1 DAY)))

Вы можете использовать UNION ALL:

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND 24hr = 'yes'
AND user.last_mail < DATE_SUB(NOW(), INTERVAL 1 DAY)

UNION ALL

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND 24hr = 'no'

Иногда вы обнаружите, что UNION ALL более эффективен, даже если этобольше ввода, так как ядро ​​базы данных может найти более оптимальный план выполнения.

0 голосов
/ 21 июля 2011

Полагаю, вы можете искать это:

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND (
  (24hr = 'yes' AND user.last_mail >= DATE_SUB (user.last_mail, INTERVAL 1 DAY))
  OR 24hr = 'no'
)

Но я бы порекомендовал вам переформулировать его, используя JOIN, например:

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users AS user
JOIN (wine_user_settings AS us, wine_subscriptions AS sub)
ON (us.id = user.id AND us.id = sub.user_id)
WHERE sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND (
  (24hr = 'yes' AND user.last_mail >= DATE_SUB (user.last_mail, INTERVAL 1 DAY))
  OR 24hr = 'no'
)

Не то чтобы я мог это проверить.

0 голосов
/ 21 июля 2011

Вы можете использовать Союз, если я не правильно прочитал ваш вопрос:

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND if(24hr = 'yes') user.last_mail >= DATE_SUB (user.last_mail INTERVAL 1 DAY)
 UNION ALL
SELECT user.username, user.email, user.id, user.last_mail, us.24hr
  FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND 24hr = 'No'
0 голосов
/ 21 июля 2011

Я предполагаю из вашего вопроса, что должно быть выполнено 1 из следующих 2 условий:

A.пользователи, которые выбрали NO in us.24hr

B.пользователи, которые выбрали YES in us.24hr и НЕ получили электронное письмо за последние 24 часа

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND (
     user.receive_mail = 'no'
 OR (user.24hr = 'yes'
AND  DATE_SUB(user.last_mail interval 1 day) > user.last_Mail)
    )
0 голосов
/ 21 июля 2011

Посмотрите, поможет ли это.

SELECT user.username, user.email, user.id, user.last_mail, us.24hr
FROM wine_users user, wine_subscriptions sub, wine_user_settings us
WHERE user.id = sub.user_id
AND us.id = user.id
AND sub.wine1 = 'yes'
AND user.receive_mail = 'yes'
AND ( (24hr = 'yes' AND user.last_mail >= DATE_SUB (user.last_mail INTERVAL 1 DAY)) OR 24hr='no')
...