如何不获得任何行,如果没有在两个表


How to not obtain any row if there is nothing in both tables?

在我们的网站上,我有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(零)。
它是漂亮的,但我不想测试一些独特的字段(如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子句中的连接条件。显式连接比隐式连接更强大。