Need help with data arrays |
Hi,
Got two tables, Staff and Events. For a view, I need to get all the Staff records and, for each record, get a SUM of all the related (by Staffid) amount fields in Events. What I'd like is to have all the data from each record in Staff and the SUM total in the same array ...I just can't figure out a way to do that. Here's what I've got so far ... get all the Staff data and do a foreach loop to call a method to get the SUM total... but how to marry the two together??? Controller: PHP Code: public function list_all_staff() Model method to get sum: PHP Code: function count_events($par_id) (03-14-2015, 08:28 AM)blackbulldog Wrote: Got two tables, Staff and Events. For a view, I need to get all the Staff records and, for each record, get a SUM of all the related (by Staffid) amount fields in Events. Getting the parent record and then looping through the child records is indeed how you would do it without the benefit of an SQL-type database. Fortunately, with an SQL-type database, we can do that all in one query. The trick is to join the two tables, and use the SUM() function and the GROUP BY clause to get a summary. Here's an example. It's not cut-and-paste code, but it should illustrate what I mean. Suppose you have two tables, parents and children. In children, each record is somebody's child, and the children.parents field is the foreign key that points to which parent is that child's parent. The child table also has how many toys each child has. So, the question is, how may toys has each parent bought for the children? Code: table parents In MySQL you would have something like this. Code: SELECT In the above query, the INNER JOIN ties the two tables together according to the ON match, but the intermediate result gives us a table with one row for every child, and we really want one row for every parent. That's what the GROUP BY clause does. The output will be a table more or less like this. Code: p_id p_name total_num_of_toys And in Codeigniter, you can return the query in an array. I do not use the DB helper functions. I just use $this->db->query('and put the SQL query here'); Do you have phpMyAdmin or some kind of SQL interface that lets you enter queries? It's very useful to have one because you can then try this and that and see the results.
Hey, don't work without a PHP debugger. Several free IDEs have this features built in. Two are NetBeans and CodeLobster. Without a debugger, it's like you're driving with a blindfold on -- you are going to crash!
(03-14-2015, 04:01 PM)RobertSF Wrote:(03-14-2015, 08:28 AM)blackbulldog Wrote: Got two tables, Staff and Events. For a view, I need to get all the Staff records and, for each record, get a SUM of all the related (by Staffid) amount fields in Events. Thank you for your detailed reply. Your suggestion works perfectly for me. (03-15-2015, 05:04 AM)blackbulldog Wrote: Thank you for your detailed reply. Your suggestion works perfectly for me. You're welcome! Glad to be of help.
Hey, don't work without a PHP debugger. Several free IDEs have this features built in. Two are NetBeans and CodeLobster. Without a debugger, it's like you're driving with a blindfold on -- you are going to crash!
Sorry to be a pain but I've just realised that I need to SUM two differnet types of data from the 'children' table - eg
PHP Code: table parents If the children table had a toytype filed then I need to separately SUM children.toys where toytype =1 and another SUM for where toytype = 2 How can I do that? Is it possible in one query? Thanks again. (03-16-2015, 04:46 AM)blackbulldog Wrote: Sorry to be a pain . . . Hey, no problem. The forum is to ask questions. Anyway, yes, you can do that with one query. Suppose you have tables like this. Code: Table: parents Here's the query. Code: SELECT Code: id name ttype numtoys What is your MySQL setup? I really suggest you get phpMyAdmin, which lets you test different queries. There's an actual free desktop application out there called MySQL Admin, but it is very sluggish, and I found it hard to understand. Consider also getting an SQL book. I like "Simply SQL," by Rudy Limeback. It's $9.99 on Kindle, and you can also get it used. The book really helped me understand joins.
Hey, don't work without a PHP debugger. Several free IDEs have this features built in. Two are NetBeans and CodeLobster. Without a debugger, it's like you're driving with a blindfold on -- you are going to crash!
(03-16-2015, 12:34 PM)RobertSF Wrote:Thanks again for coming back and explaining clearly. I've got phpmyadmin and have been using it most of the day to try to get what I want from my database. I don't think I was very good at explaining the nature of the problem. I'm building a staff absence tracking application so Ihave multiple staff and multiple absence 'types' the 'parent' table is staff and the 'child' table is events ... therecan be multiple different absence types in in my child table and I only need totals of two of them ... I also have to select events that occur in a date range. However, the good news for me is that I've come up with a solution (inspired by your previous post) and here it is:(03-16-2015, 04:46 AM)blackbulldog Wrote: Sorry to be a pain . . . Code: $SQLstring="SELECT * This gives me to total of event type 1 and the total of event type 2 between the relevant dates for each member of staff. The result set contains the staffid 3 times (once from the SELECT * and once each because of the select in the subqueries) and I don't know how to get rid of the two 'extra' ones. Also, if there are no records of the specified type in the date range for any staff member the the totals return as NULL ... is there a way to get the query to return 0 rather than NULL? also, is this solution a good one or could I have done better?
Ah, I think I understand now. You want one row per staff member and the total for each absence type on the same row, like this?
Code: id name absent sick Quote:blackbulldog: I'm getting out of my depth here (my SQL isn't that good), LOL, but there's a function called COALESCE() that should do the trick. The COALESCE() function returns the first non-NULL value from a list of values. I think you'll have to use it on both fields. Code: instead of
Hey, don't work without a PHP debugger. Several free IDEs have this features built in. Two are NetBeans and CodeLobster. Without a debugger, it's like you're driving with a blindfold on -- you are going to crash!
(03-16-2015, 01:27 PM)blackbulldog Wrote: This gives me to total of event type 1 and the total of event type 2 between the relevant dates for each member of staff. The result set contains the staffid 3 times (once from the SELECT * and once each because of the select in the subqueries) and I don't know how to get rid of the two 'extra' ones.Oh, cool, that's easy! Instead of doing SELECT *, just name the fields that you want. From your two subqueries, I think you only need the SUM() fields, a.total_absence and s.total_sickness. (03-16-2015, 01:27 PM)blackbulldog Wrote: also, is this solution a good one or could I have done better?I played and played with it and couldn't find anything better. I think you got it! Don't forget the COALESCE() tip I posted below. I tested it, and it works. That was a great question you posted! I learned from trying to find a solution!
Hey, don't work without a PHP debugger. Several free IDEs have this features built in. Two are NetBeans and CodeLobster. Without a debugger, it's like you're driving with a blindfold on -- you are going to crash!
Quote:From your two subqueries, I think you only need the SUM() fields, a.total_absence and s.total_sickness. I've tried leaving out the events.eventid in the subquery select but that throws the following error: Code: Error Number: 1054 so it seems to need the fields explicitly selected so it can do the join maybe? It's no big deal though, I can live with having the extra data in the result set. Just another point to note ... I've found that specifying the COALESCE like this, with the closing bracket after the AS variable: Code: COALESCE(SUM(amount) AS total_absence, 0) throws an error. Whilst specifying it like this (with closing brackets after the SUM(amount)) Code: COALESCE(SUM(amount),0) AS total_absence Thanks for your help, I learned a lot too. I'll pick up a copy of that book too! |
Welcome Guest, Not a member yet? Register Sign In |