2013-06-22 4 views
0

Работа с двумя таблицами в Postgres: Members и Membership. Членство имеет столбец end_date, который может быть NULL, если членство все еще запущено. Как только оно закончится, или дата окончания известна (может быть будущее), поле заполняется датой.Поиск записей на основе возвращенных записей из связанной таблицы

Теперь я хотел бы найти всех членов, которые не имеют активного членства на данный момент (или: только членство с end_dates, установленное и в прошлом или 0 членство). Члены могут иметь более 1 членства, очевидно.

Я делаю это в проекте Rails (3.2) и хотел бы иметь возможность использовать ActiveRecord, если это возможно, но при необходимости будет выполняться прямой SQL (хотя я знаю ActiveRecord лучше).

Я пытался найти все виды вещей с подзапросами, но я не могу найти способ, чтобы выбрать строки, где графы конкретных строк в соответствующей таблице 0.

Я прибегая к помощи довольно через некоторое время, но у них закончились идеи о том, как их искать. Большинство ответов касаются поиска записей, которые соответствуют критериям, и я чувствую, что не хочу тех, которые не совпадают. Может быть, это вопрос новичков, или я неправильно настроен. В таком случае: пожалуйста, просветите меня, я только начинаю.

Основываясь на частичном ответе Якуба, я пробовал намного больше. На данный момент у меня есть следующий запрос:

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 ... part). Тем не менее, я ожидаю, что члены с истекшим членством и текущие членства также будут возвращены, так как 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

Это становится довольно близко, но еще не завершена. Если я опустил раздел «ИЛИ ....», я найду членов с членством, которые закончились, но если они добавят новое членство, они все равно выйдут вперед, хотя они снова станут участниками. – Kobes

+0

Должен был добавить это: Кроме того, s.end_date IS NULL будет правдой для любого в текущем членстве, так как любое текущее членство не будет иметь дату окончания. Я пытаюсь получить граф, помещенный где-то, но я не могу заставить его работать. Если количество членств для m.id равно 0 или все s для m.id имеют «end_date Kobes