Reputation: 342
I'm struggling with SQL and would value some assistance.
I have a main table and a one-to-many link table in mySQL, joined by oppreg_id. I want to retrieve all the records on the main table that have multiple matches to the field activity_id in the link table.
main table link table
oppreg oppreg2activity
--------------- -----------------
oppreg_id ----> oppreg_id
title activity_id
description
end_date
...
So I might have
oppreg_id = 4563 in the main table
and records in the oppreg2activity table
oppreg_id activity_ID
4563 27e17f2e
4563 38d6bd73
4563 ....
I've tried SQL like
SELECT oppreg.`oppreg_id`,`title`,`description`, activity_id
FROM `oppreg`
INNER JOIN oppreg2activity ON oppreg.oppreg_id = oppreg2activity.oppreg_id
GROUP BY `oppreg_id`
HAVING
activity_id = '27e17f2e'
AND activity_id = '38d6bd73'
This works when one WHERE item is present but fails on multiple ones.
I also need to include the additional restriction
oppreg.end_date >= CURDATE()
but can't see how to include this.
Upvotes: 0
Views: 30
Reputation: 521419
Your suggestion to aggregate by oppreg_id
is correct, but you should but asserting counts in the HAVING
clause, instead of using plain equalities.
SELECT
o.oppreg_id
FROM oppreg o
INNER JOIN oppreg2activity oa
ON o.oppreg_id = oa.oppreg_id
WHERE
oa.activity_id IN ('27e17f2e', '38d6bd73') AND
o.end_date >= CURDATE()
GROUP BY
o.oppreg_id
HAVING
COUNT(DISTINCT activity_id) = 2;
Note that it only makes sense to select the title
and description
if the oppreg_id
column be a primary key in the oppreg
table. If not, then we would have to do an additional join to bring in this extra information.
As for an explanation of the query, it works by attempting to reduce down each oppreg_id
group to only those records having the two specified activity_id
values. It then aggregates and asserts using COUNT
that two distinct activity_id
are present, which, if true, implies that this oppreg_id
group is a match.
Upvotes: 3
Reputation: 31993
i think you need where for filter date and count
for multipe entry checking
SELECT oppreg.`oppreg_id`,
`title`,`description`, activity_id
FROM `oppreg`
INNER JOIN oppreg2activity ON oppreg.oppreg_id = oppreg2activity.oppreg_id
where oppreg.end_date >= CURDATE()
GROUP BY oppreg.`oppreg_id`,
`title`,`description`, activity_id
having count(*)>1
Upvotes: 1