2012-01-17 62 views
1

我有如下两个MySQL表:如何用LEFT JOIN修复这个SQL?

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 

我的问题是,如果没有订阅特定的包,查询不会显示包。

我必须表现出所有的页面和....如果用户已经订阅检查MAX到期日(becase的我跟踪所有用户所做的subscrions)。

我该怎么让所有的包和相关用户的到期日期? (如果没有订阅包显示NULL)

回答

1

您正在按subscriptions.id_user进行分组,但您从packages表中选择了所有非聚集。你确定你是按正确的字段分组吗?

它看起来应该是packages.id ...

+0

是不正确的,正确的.... packages.id – Dail 2012-01-17 12:25:24

+0

@Dail - 伟大的,有在GROUP BY不同领域确实现在你的查询工作? :) – MatBailie 2012-01-17 12:28:06

+0

是的,它完美的作品 – Dail 2012-01-17 12:29:01

0

容易...只需移动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,和一个伟大的伎俩要记住。

注意:您GROUP BY列表太

+0

我认为这是不正确的。由于packages表位于连接的左侧,因此在where子句中使用'packages.visible'引用不成问题。此外,建议的SQL现在显示所有包,即使它们不可见,但只是不加入对不可见包的订阅。 * [我认为这只是GROUP BY,那是错误的。因为它是MySQL,你只需要GROUP BY唯一标识符,而不是package表中的每个字段。] * – MatBailie 2012-01-17 12:21:55