如果两个表中什么都没有,怎么不获取任何行?

时间:2014-07-27 17:27:15

标签: php mysql sql

在我们的网站上,我有profile.php文件,使用以下SQL查询从数据库生成特定于用户的配置文件。

select
    u.username,
    u.email,
    u.access,
    date_format(u.registerdate, '%e. %c. %Y') as `registered`,
    date_format('00-00-0000 00:00', '%e. %c. %Y') as `last_visited`,
    count(p.id) as `posts`
from
    users u,
    posts p
where
    u.username = ? AND p.post_creator = u.id
;

下面我测试用户是否存在他的所有数据,使用mysql_num_rows()函数(请避免评论使用已弃用的PHP的MYSQL扩展,我只是在改进朋友的旧代码)

问题来了,因为如果我在WHERE子句中键入未使用的用户名(替换问号),而不是返回预期的空结果集MySQL数据库,则返回一行,填充大多数字段使用NULL s,last_visit包含预期0. 0. 0000posts包含0(零)。
这很漂亮,但我不想在我的PHP脚本中测试一些独特的字段(例如u.username)是否为空/ NULL,因为那是非常脏的检查方式。

我仍想获得空的结果集。我尝试JOIN,然后WHERE (...) AND u.id is not null,但两者都没有效果(没有行为改变)。然后我尝试了HAVING u.id is not null,在向SELECT (...)表达式添加了一列之后,它就起作用了 但我知道HAVING子句用于在select之后过滤结果集。我在问你:

有更清洁的方法吗?在SELECT期间提及以这种方式过滤行。 (或者这是一个好习惯吗?我的问题没有找到答案。)

1 个答案:

答案 0 :(得分:0)

我相信你的问题是由group by的一些奇怪行为引起的。没有行总是的聚合查询返回一行,即使所有行都被过滤掉也是如此。具有group by的聚合查询可以返回0行。所以,我想你只想添加group by

select u.username, u.email, u.access,
       date_format(u.registerdate, '%e. %c. %Y') as `registered`,
       date_format('00-00-0000 00:00', '%e. %c. %Y') as `last_visited`,
       count(p.id) as `posts`
from users u join
     posts p
     on p.post_creator = u.id
where u.username = ?
group by u.username;

请注意,我还将查询更改为使用join子句中的连接条件的显式on语法。显式连接比隐式连接更强大。