Как исправить этот sql с LEFT JOIN? - PullRequest
1 голос
/ 17 января 2012

У меня есть две таблицы mysql:

mysql> desc subscriptions;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(6)       | NO   | PRI | NULL    | auto_increment |
| id_user    | int(6)       | NO   | MUL | NULL    |                |
| id_package | int(4)       | NO   |     | NULL    |                |
| expiry     | date         | YES  |     | NULL    |                |
| ip         | varchar(100) | NO   |     | NULL    |                |
| amount     | double       | NO   |     | NULL    |                |
| processed  | tinyint(4)   | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)


mysql> desc packages;
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | int(6)       | NO   | PRI | NULL    | auto_increment |
| id_panel | tinyint(4)   | NO   |     | NULL    |                |
| name     | varchar(100) | NO   |     | NULL    |                |
| price    | double       | NO   |     | NULL    |                |
| period   | varchar(50)  | NO   |     | NULL    |                |
| days     | int(11)      | NO   |     | NULL    |                |
| visible  | tinyint(4)   | NO   |     | NULL    |                |
| payment  | tinyint(4)   | NO   |     | 1       |                |
+----------+--------------+------+-----+---------+----------------+
8 rows in set (0.00 sec)

Я использую следующий запрос для извлечения всех пакетов и относительной даты истечения срока действия ПОЛЬЗОВАТЕЛЯ (для конкретного пакета).

SELECT packages.id, packages.name, packages.price, packages.period, packages.days, MAX(subscriptions.expiry) as expiry
FROM packages LEFT JOIN subscriptions
ON subscriptions.id_package = packages.id AND subscriptions.processed = 1 AND subscriptions.id_user = 1
WHERE packages.visible = 1
GROUP BY subscriptions.id_user
ORDER BY packages.id_panel

Моя проблема в том, что если нет подписки на конкретный пакет, запрос не показывает пакет.

Я ДОЛЖЕН показать всю страницу и .... ЕСЛИ у пользователя есть подписка, проверьте дату истечения срока действия МАКСА (потому что я отслеживаю всех подписчиков, сделанных пользователем).

Как я могу показать все пакеты и относительные даты истечения срока действия пользователя? (и при отсутствии подписки на пакет покажите NULL)

Ответы [ 2 ]

1 голос
/ 17 января 2012

Вы группируете по subscriptions.id_user, но вы выбираете все свои неагрегаты из таблицы packages.Вы уверены, что группируете по правильному полю?

Похоже, это должно быть packages.id ...

0 голосов
/ 17 января 2012

Легко ... просто переместите условие packages.visible = 1 в предложение ON!

SELECT packages.id, packages.name, packages.price, packages.period, packages.days, MAX(subscriptions.expiry) as expiry
FROM packages
LEFT JOIN subscriptions ON subscriptions.id_package = packages.id
    AND subscriptions.processed = 1
    AND subscriptions.id_user = 1
    AND packages.visible = 1
GROUP BY 1,2,3,4,5
ORDER BY packages.id_panel

Этот подход - только способ получить условия в LEFT JOINи отличный трюк для запоминания.

Примечание: Ваша группа по списку тоже была неверна

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...