Why are you determining a member's absence through another member's presence?
I guess there must be an events
table in your schema. And I would expect it to have a column called something like event_date
. It's the event_date
column that you should use to determine which events a member could visit (members.registration_date < events.event_date
).
After getting the list of members and their respective valid events, you can anti-join it to the attendance
table to see which member missed which (or how many) events.
Here's an example query illustrating what I just said. It implements the anti-join using LEFT JOIN
+ WHERE IS NULL
check:
SELECT
m.member_id,
e.event_id
FROM members m
INNER JOIN events e ON m.registration_date < e.event_date
LEFT JOIN attendance a ON m.member_id = a.member_id
AND e.event_id = a.event_id
WHERE a.member_id IS NULL
AND ... /* some other conditions to filter members and/or events, if necessary */
Or here's another example showing how you could count total events available to a member and those actually attended by him/her:
SELECT
m.member_id,
COUNT(e.event_id) AS total_events,
COUNT(a.event_id) AS attended_events,
FROM members m
INNER JOIN events e ON m.registration_date < e.event_date
LEFT JOIN attendance a ON m.member_id = a.member_id
AND e.event_id = a.event_id
WHERE /* some conditions as necessary */
Note that in the last example there's no IS NULL
check. It's because that query needs to get all the events per member. Missed events are just not counted by the COUNT()
function (because the corresponding a.event_id
value contains NULL in those cases).
UPDATE
Since, as per your comment, the events are recurring (and thus have no fixed dates), I would suggest adding and using an event_calendar
table, populated beforehand either manually or programmatically. Naturally, the events
table in the above examples would be replaced with event_calendar
.
Alternatively, if maintaining an event calendar is not an option, you could replace events
in your queries with
(
SELECT DISTINCT
event_id,
attendance_date AS event_date
/* or, if they are not purely dates:
CAST(attendance_date AS date) AS event_date
*/
FROM attendance
) e
(basically, @ypercube's suggestion with dates thrown in).
You don't need all the derived tables. You are joining the basic (product
) too many times. You can write the query joining it only once.
Compound indices are a must for EAV designs. Try adding an index on (attribute_id, product_id, value)
and then the query:
SELECT t0.id,
t1.`value` AS length,
t2.`value` AS height,
t3.`value` AS family
FROM
products t0
INNER JOIN
product_eav_decimal t1
ON t1.product_id = t0.id
AND t1.attribute_id = 91
AND t1.`value` BETWEEN 15 AND 35
LEFT JOIN
product_eav_decimal t2
ON t2.product_id = t0.id
AND t2.attribute_id = 80
--
--
--
LEFT JOIN -- LEFT or INNER join
product_eav_decimal t6
ON t6.product_id = t0.id
-- AND t6.attribute_id =
ORDER BY t0.id ASC ;
Best Answer
Something like this would give you the total across all three of those days:
If you wanted the total separately for each of those dates, use this:
Try this for overall attendance. Keep in mind I didn't have time to setup the schema, so this is untested: