简体   繁体   中英

Join assistance

I have a table (Attendance Table) that records attendance statistics. In each row, there are the following:

  • Event Date (date)
  • Member ID (int)
  • Event ID (int)
  • Attended (bit)

Only if a member is marked in attendance will a row be present with a "1" for Attended. There are a few exceptions where someone clicked them by mistake and then toggled them back in which case the Row will contain a "0".

Then I have another table (Dates Table) that has a list of all the possible Event Dates.

I'm looking for a way to show a listing of every possible date for a specific attendee to show if there were present or not. I've tried a few JOIN combinations but am having trouble getting values for dates that do not have an associated row in the Attendance table.

I know I could do this with a FOREACH LOOP in my App Code, but I would prefer to let the DB Engine do the work since it's much more efficient.

I would like to have output similar to:

  • EventDate (From Dates Table)
  • MemberID (From Attendance Table)
  • EventID (From Attendance Table)
  • Attended (From Attendance Table) - This will be either a 0 or 1

Thanks in advance for your assistance.

UPDATED:

Here is an example of data in the Attendance Table for a specific member in the month of August.

Attendance Table Sample

Here is an example of data in the Dates Table that shows all potential dates in month of August.

Dates Table Sample

If the Member wasn't present on a specific day, I want to be able to show this....there will be either a NULL record or a (0) in the Attended column of the Attendance Table if they were not present.

I think you can use a left join with some aggregation. Assuming you have tables for members and dates, then:

select e.*, m.memberid, coalesce(a.attended, 0) as attended
from members m cross join
     events e left join
     (select eventid, memberid, max(attended) as attended
      from attendance a
      group by eventid, memberid
     ) a
     on m.memberid = a.memberid and e.eventid = a.eventid;

If you don't have separate tables for members and events, you an use a subquery, such as (select distinct memberid from attendance) instead.

I think I figured it out....

SELECT tad.date, DAYNAME(tad.date) as Day,
    (SELECT COUNT(*)
    FROM attendance a
    WHERE a.MemberID = pMemberID
    AND a.ServiceTypeID = 1
    AND a.Date = tad.date) AS Attended_SS,

    (SELECT COUNT(*)
    FROM attendance a
    WHERE a.MemberID = pMemberID
    AND a.ServiceTypeID = 2
    AND a.Date = tad.date) AS Attended_AM,

    (SELECT COUNT(*)
    FROM attendance a
    WHERE a.MemberID = pMemberID
    AND a.ServiceTypeID = 3
    AND a.Date = tad.date) AS Attended_PM,

    (SELECT COUNT(*)
    FROM attendance a
    WHERE a.MemberID = pMemberID
    AND a.ServiceTypeID = 4
    AND a.Date = tad.date) AS Attended_WED

FROM t_AllDates tad
WHERE tad.date BETWEEN pStartDate AND pEndDate;

Which generates the following output (not perfect, but will work for me)

Output

Thanks for the help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM