2013-06-22 123 views
0

处理Postgres中的两个表:成员和成员资格。成员资格有一个end_date列,如果成员资格仍在运行,则该列可以为NULL。一旦结束,或结束日期已知(可能是未来),该字段将填入日期。根据相关表中没有返回的记录查找记录

现在我想查找所有当前没有活动成员资格的成员(或者:只有带有end_dates的成员资格,过去或0个成员资格)。成员显然可以有1个以上的成员。

我在Rails(3.2)项目中这样做,并希望能够在可能的情况下使用ActiveRecord,但如果需要,直接SQL将会执行(尽管我更了解ActiveRecord)。

我试图找到各种各样的事情与子查询,但我不能找到一种方法来选择行,其中在相关表中特定的行数为0

我一直在谷歌上搜索了很现在有一段时间了,但已经没有了关于如何搜索的想法。大多数答案都是为了找到符合标准的记录,而我觉得我不会那些不符合标准的记录。也许这是一个新手问题,或者我的目标是错误的。在这种情况下:请赐教,我刚刚开始。

基于Jakub的部分回答,我尝试了更多。目前,我有以下查询:

SELECT 
    m.id, m.first_name, m.last_name, COUNT (ms.id) AS n_memberships 
FROM 
    members AS m 
LEFT JOIN memberships AS ms 
ON m.id = ms.member_id 
GROUP BY m.id, ms.end_date 
HAVING (max(ms.end_date) < now() AND NOT COUNT(ms.end_date = NULL) > 0) OR COUNT(ms.id) = 0;

这将返回所有成员根本没有成员(没有过去也没有当前)。基于HAVING子句的最后部分(OR ...部分)。 但我期望会员过期成员资格,并且不会返回当前成员资格,因为max(ms.end_date)将返回一个比现在更少的值,并且没有给定结束日期将不会有成员资格。这不会发生,任何想法?

回答

1

你在找什么是OUTER JOIN。在SQL代码中查找成员没有成员是:

SELECT m.id 
FROM members AS m 
LEFT JOIN memberships AS s 
    ON m.id=s.member_id 
WHERE s.id IS NULL; 

完整的查询:

SELECT m.id 
FROM members AS m 
LEFT JOIN memberships AS s 
    ON m.id=s.member_id 
GROUP BY m.id 
HAVING max(s.end_date)<now() OR max(s.end_date) IS NULL 
+0

它越来越相当接近,但尚未完成。如果我省略了“OR ....”部分,我会找到会员资格已经结束的会员,但是如果他们添加了新会员资格,他们仍然会出面,尽管他们再次成为会员。 – Kobes

+0

应该加上这个:此外,对于当前成员中的任何人,s.end_date IS NULL将为真,因为任何正在运行的成员资格都不会有结束日期。我试图把计数放在某个地方,但我无法让它工作。如果m.id的成员关系计数为0,或者m.id的所有s都具有'end_date Kobes

相关问题