1

Sorry the title is very vague.

Basically, I'm stuck with something. I have an ample working script which lists from two tables.

It pulls a list of events

Event 1
Event 2
Event 3
Event 4
Event 5
Event 6

Now, users need t-shirts for the "overall" event. They are volunteers, and they have t-shirts. When they submit which events that can help steward, they choose their t-shirt size so I can order them.

I then get a list

Event 1:
Small = Count
Medium = Count
Large = Count

When the volunteer enters their t-shirt size, it is saved in their PROFILE. The events are stored in a table called events.

However, that part isn't important. I can easily get it to list as above and it does count correct, to a certain extent. The problem is, say I have a volunteer called Bob. Bob's t-shirt size is Small. He is only volunteering for Event 1. NO OTHER VOLUNTEERS HAVE ENTERED THE DAYS THEY CAN HELP YET. So I would have all events listed, and the only area that would equal anything other than 0 is

Event 1 - Small = 1, Medium = 0, Large = 0 Event 2 - Small = 0, Medium = 0, Large = 0 etc. etc....

Anyway, say Bob decides to help at Event 1,2,3 and 5.

It is then showing Event 1 - Small = 1, Medium = 0, Large = 0
Event 2 - Small = 1, Medium = 0, Large = 0
Event 3 - Small = 1, Medium = 0, Large = 0
Event 4 - Small = 0, Medium = 0, Large = 0
Event 5 - Small = 1, Medium = 0, Large = 0
Event 6 - Small = 0, Medium = 0, Large = 0

It's showing that because the query is basically

SELECT u.id, u.userid, u.eventid, u.helping, i.userid, i.tshirt_size FROM helpers AS u LEFT JOIN profiles AS i ON u.userid=i.userid WHERE `eventid`='$eventid' AND u.helping='1' AND i.tshirt_size='$size'

I then echo that with a function, like getTShirtCount("eventid","Small");

Event ID is picked up by a MySQL Fetch Array loop, looping the Events I have in my database (which is also where the event ID is picked up from).

Event 1 = ID: 1
Event 2 = ID: 2
etc..

When they submit the events they can help, it goes into a "helpers" table, like UserID = 101
EventID = 1
Helping = 1

UserID = 101
EventID = 2
Helping = 1

UserID = 101
EventID = 3
Helping = 1

UserID = 101
EventID = 4
Helping = 0

etc...

== WHAT I WANT TO DO ==

IF the user, Bob, has been listed in Event 1 - I don't need him to be counted in ANY OTHER EVENT. The count is so that I can bring the correct amount of t-shirts to each event to distribute. So it may tell me I need 50 small, 10 large, 40 medium.

If Bob is attending Event 1, he will get his t-shirt then, so he doesn't need me to bring another (thus be counted) in any other event.

So, I am essentially needing it to ONLY add 1 to the num_rows count, IF "Bob" has no "Helping='1'" for any previous events.

I hope I've explained that well enough.

Can anyone help?

konsolenfreddy
  • 9,551
  • 1
  • 25
  • 36
TheMonk
  • 13
  • 3
  • Are the shirts for different events the same? What do you mean by previous event? Earlier date? Or do you want to count only one shirt for one user no matter how many events he selected? – piotrm Feb 21 '12 at 21:49
  • The shirts are all the same for each event. Previous events, I mean Event 2 is after Event 3 etc.... and yes, if they are attending every event, based on the query above - it will count them for 1 on "small" for each event. If they are at event 1, I don't want it to be counted in any other event, as i'll already take a tshirt for them to event 1. – TheMonk Feb 21 '12 at 21:57
  • 1
    Event 2 is after Event 3 based on what? – piotrm Feb 21 '12 at 22:13
  • Sorry sorry. Event 2 is before event 3. The events go in order. So event 1 is first. Then 2. Then 3 etc. they do have a time stamp too though in the database if that helps. But it's separate to helpers and profiles. It's in events. Eventid refers to the Id column in the events table. – TheMonk Feb 21 '12 at 22:23

5 Answers5

0

you can group_by u.userid which may help.

encodes
  • 741
  • 4
  • 18
0

I think i understand (not too sure though). try selecting a DISTINCT userid. That way a userid gets selected only once.

dee
  • 194
  • 7
0

If you simply trying to figure out how many of each size shirt you need, then you should just find all of the people that are currently registered to help out in any event and then group by shirt size. Something like this:

SELECT size,count(*) FROM helpers,users WHERE helpers.user_id = users.user_id GROUP BY size;
jasonlfunk
  • 5,159
  • 4
  • 29
  • 39
  • problem is i want to list the count per event, so I can see how many at event 1 need small....would that work? – TheMonk Feb 21 '12 at 22:05
  • when added to the helpers database, they get 6 entries per user as there are six events. 1=attending, 0=not attending...it joins the profile "tshirt_size" by the user_id. I then look for eventid = 1 and tshirt_size = small and ask for a count.... If they are also going to event 2, it counts them in that too, but I don't want it too - just event 1.... – TheMonk Feb 21 '12 at 22:10
  • I don't understand why you want a count per event. What does the count actually represent? Is there a real world problem that you are trying to solve ie. you need to know how many shirts to take to each event? – jasonlfunk Feb 22 '12 at 12:49
  • Why don't you just take all the shirts to all the events and mark people off a list when they take one? – jasonlfunk Feb 22 '12 at 12:52
  • Yes, this is a real world event that is taking place and we have over 1000 volunteers, it is not practical to take 1000 t-shirts around to all events....i want to know how many to order for delivery at each event for distribution accordingly – TheMonk Feb 22 '12 at 13:55
  • i do appreciate your help though :) – TheMonk Feb 22 '12 at 13:55
  • Isn't it likely though that some people who were supposed to come to the first event won't come but will come to the next one? Then you won't have the right number of shirts. :) – jasonlfunk Feb 22 '12 at 14:55
  • Yeah you're right, it is likely....but only the odd one or two and we intend to order an extra 2 of each size for extras per event. – TheMonk Feb 22 '12 at 15:30
  • i wish it wasn't such a nightmare, because it isn't even for me - it's for a friends company....they have around 10 events per year, all requiring volunteers. Because of the demand in t-shirts they want to order them per event, which are weeks apart...so that they take the correct amount to each event (plus an extra few). – TheMonk Feb 22 '12 at 15:32
0

I had to assume your events table has fields eventID and event_name, I could guess other tables from the query in your question.

SELECT e.event_name, 
  SUM( eh.shirt_size <=> 'Small' ) as Small,
  SUM( eh.shirt_size <=> 'Medium' ) as Medium,
  SUM( eh.shirt_size <=> 'Large' ) as Large
FROM events e
LEFT JOIN
  ( SELECT h.userID, MAX(p.tshirt_size) as shirt_size, MIN(eventID) as first_event 
    FROM helpers h
    JOIN profiles p ON p.userID = h.userID
    WHERE h.helping = 1
    GROUP BY h.userID ) eh
  ON e.eventID = eh.first_event
GROUP BY e.event_name

A working example: http://sqlfiddle.com/#!2/33f9b/1

piotrm
  • 12,038
  • 4
  • 31
  • 28
  • Hi piotrm, thank you for your help. This is sort of working for me, but I've adapted now into the full system rather than the example I gave and it's not working as expected. I'll keep working on this...and tick as answer when I can get it worked as hoped. Thank you VERY much for your help. – TheMonk Feb 22 '12 at 10:58
  • in the events table, I have years...such as 2009, 2010, 2011 and now 2012 for this years events....can I filter the view to only count events in year "2012" for example...? – TheMonk Feb 22 '12 at 13:55
  • Change `WHERE h.helping = 1` to `WHERE h.helping = 1 AND h.eventID > $countfromthisID` and add the same condition as `WHERE e.eventID > ...` before last GROUP BY – piotrm Feb 22 '12 at 17:25
  • Hey, thank you for your help. I've added that now. The page is finally displaying in my actual live environment, but the count is incorrect at the moment, in-fact the count doesn't resemble any correct amounts so far (For example over the full years events I should have 5 small and I have 0 apparently)....so I will keep working on it to see where I am going wrong. You've pointed me in the right direction though, so thank you very much. – TheMonk Feb 22 '12 at 19:27
0

I chose not to pivot the table for you, and to keep the query simple (for optimization), though long. I did it as three separate queries, one for each size, then joined them with UNION:

(SELECT MAX(e.eventid) AS eventid, MAX(e.event_name) AS event_name,
   MAX(p.tshirt_size) AS size, COUNT(*) AS tshirt_count
FROM Helpers h
JOIN Events e
  ON e.eventid = h.eventid
JOIN Profile p
  ON p.user_id = h.user_id
LEFT JOIN Events e2
  ON e2.eventid < e.eventid
JOIN Helpers h2
  ON h2.eventid = e2.eventid
  AND h2.user_id = h.user_id
WHERE p.tshirt_size = 'small'
  AND e2.eventid IS NULL
GROUP BY e.eventid)
UNION ALL
(SELECT MAX(e.eventid) AS eventid, MAX(e.event_name) AS event_name,
   MAX(p.tshirt_size) AS size, COUNT(*) AS tshirt_count
FROM Helpers h
JOIN Events e
  ON e.eventid = h.eventid
JOIN Profile p
  ON p.user_id = h.user_id
LEFT JOIN Events e2
  ON e2.eventid < e.eventid
JOIN Helpers h2
  ON h2.eventid = e2.eventid
  AND h2.user_id = h.user_id
WHERE p.tshirt_size = 'medium'
  AND e2.eventid IS NULL
GROUP BY e.eventid)
UNION ALL
(SELECT MAX(e.eventid) AS eventid, MAX(e.event_name) AS event_name,
   MAX(p.tshirt_size) AS size, COUNT(*) AS tshirt_count
FROM Helpers h
JOIN Events e
  ON e.eventid = h.eventid
JOIN Profile p
  ON p.user_id = h.user_id
LEFT JOIN Events e2
  ON e2.eventid < e.eventid
JOIN Helpers h2
  ON h2.eventid = e2.eventid
  AND h2.user_id = h.user_id
WHERE p.tshirt_size = 'large'
  AND e2.eventid IS NULL
GROUP BY e.eventid)
ORDER BY eventid, size = 'large', size = 'medium', size = 'small'

This will return results like this:

Event1       Small       1
Event1       Medium      0
Event1       Large       0
Event2       Small       0
Event2       Medium      0
Event2       Large       0
...

This query assumes that the events are ordered chronologically by eventid.

Marcus Adams
  • 53,009
  • 9
  • 91
  • 143