在我们的网站上,我有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. 0000
和posts
包含0
(零)。
它是漂亮的,但我不想测试一些独特的字段(如u.username
)是否他们不是空/NULL
或不,在我的PHP脚本,因为这是非常肮脏的方式来检查。
我仍然想获得空结果集。我尝试了JOIN
,然后WHERE (...) AND u.id is not null
,但两者都不起作用(没有行为改变)。然后我尝试了HAVING u.id is not null
,并在为SELECT (...)
表达式添加了一列后,它起作用了。
但是我知道HAVING
子句是用来在select之后过滤结果集的。我问你:
有更干净的方法吗?提到以这种方式过滤行,而SELECT
。(或者这是一种好的做法?
我相信你的问题是由于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
子句中的连接条件。显式连接比隐式连接更强大。