Optimizing a lot of foreach loops. Please help.

Reply

Join Date: Sep 2007
Posts: 18
Reputation: tomjohnson is an unknown quantity at this point 
Solved Threads: 0
tomjohnson tomjohnson is offline Offline
Newbie Poster

Optimizing a lot of foreach loops. Please help.

 
0
  #1
Aug 18th, 2008
Hello everyone. I have never really ever had a handle on nested loops and would like to optimize this piece of code. What I have works but I am not happy with it. The first query sets up the customer_id and the location_id for the rest of the loops. (Not a good way to handle this)

Here is my code:

<?php
require_once("db.php");
$db = new Database();
$rpthdr = $db->Query("SELECT t1.customer_id, t1.location_id, t1.location_name, t2.name FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) GROUP BY t2.customer_id, t2.location_id");

foreach($rpthdr as $hdr)
{
	$customer_id = $hdr['customer_id'];
	$location_id = $hdr['location_id'];
	echo $hdr['location_name']."<br>";
	echo $hdr['name']."<br>";

	$report1 = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = 'report1'");
	foreach($report1 as $rpt1)
	{
		echo "$rpt1[report]"."<br>";
	}

	$report2 = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = 'report2'");
	foreach($report2 as $rpt2)
	{
		echo "$rpt2[report]"."<br>";
	}

	$report3 = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = 'report3'");
	foreach($report3 as $rpt3)
	{
		echo "$rpt3[report]"."<br>";
	}
}
?>

I have a plain old html page that I wanted to use str_replace on to populate these database fields. I couldn't seem to get that working though. I then decided to try and procedurally write code that would at least give me my data in the format I expect. That is the code above.

Ideally, I would like to have a small foreach and or while loop to handle this and then use str_replace. Failing that, I will have to incorporate the html into this code.

Also, please notice that the sql statements for report1, 2 and 3 are identical with exception of the "report_type in the WHERE clause". It seems to me that there has to be a much better way to do this.

Can someone please help???

Thanks. Tom
Last edited by tomjohnson; Aug 18th, 2008 at 11:12 pm.
Reply With Quote Quick reply to this message  
Join Date: Aug 2008
Posts: 381
Reputation: langsor is an unknown quantity at this point 
Solved Threads: 33
langsor langsor is offline Offline
Posting Whiz

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #2
Aug 18th, 2008
I can show you how to replace the code in your html file without using string replace ... if you'd like to go with that option.

Otherwise I'm having a difficult time visualizing the data we're actually working with here -- on the other hand, I want you to write my sql if I ever build a real web-app.

If you'd rather use loops over this other (PHP-DOM) method I have in mind, please help me see the data we're trying to process and into what format you would like the end result.

Thanks
Reply With Quote Quick reply to this message  
Join Date: Sep 2007
Posts: 18
Reputation: tomjohnson is an unknown quantity at this point 
Solved Threads: 0
tomjohnson tomjohnson is offline Offline
Newbie Poster

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #3
Aug 18th, 2008
Hi langsor. Thank you for the response, help and comment about my sql. I'd be happy to help. I have always been more of a database guy than a programmer.

Let me see if I can try and give you some sample data here. And, by the way, I am interested in anything that will allow me to import my data fields as long as it is not Smarty (template system)

This would be a *SINGLE* report for say KMart.
location_name name
KMart Tom

report1
this would be the actual db field having the report type of "1" and all the report data for report1.
report2
this would be the actual db field having the report type of "2" and all the report data for report2.
report3
this would be the actual db field having the report type of "3" and all the report data for report3.
Then we would need to start a brand new template with a new customer from this loop.

Thanks again for the help.
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 849
Reputation: R0bb0b is on a distinguished road 
Solved Threads: 67
R0bb0b's Avatar
R0bb0b R0bb0b is offline Offline
Practically a Posting Shark

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #4
Aug 18th, 2008
well first off you can do
t3.report_type in ('report1', 'report1', 'report1')

instead of doing a separate query for each.
“Be who you are and say what you feel because those who mind don't matter and those who matter don't mind.” - Dr. Seuss

-- The documentation is inevitable, you may get away with it for a little while but eventually you too will have to do the deed.
Reply With Quote Quick reply to this message  
Join Date: Aug 2008
Posts: 381
Reputation: langsor is an unknown quantity at this point 
Solved Threads: 33
langsor langsor is offline Offline
Posting Whiz

Re: Optimizing a lot of foreach loops. Please help.

 
1
  #5
Aug 19th, 2008
I keep learning SQL as I go ... like everything ... R0bb0b is great with SQL and PHP from what I've seen so far :-)

First off let me give an example of some methods you might be able to use to update values in your html template page ... if it is just plain html.

test.html
  1. <html>
  2. <head>
  3. <script type="text/javascript">
  4. </script>
  5. </head>
  6. <body>
  7. <h1 id="my_id"></h1>
  8. <p>Some content</p>
  9. </body>
  10. </html>

examples.php
  1. <?php
  2.  
  3. $doc = new DOMDocument('1.0');
  4. $doc->loadHTMLFile( 'test.html' );
  5.  
  6. // or load html as a string ...
  7. //$doc->loadHTML( file_get_contents( 'test.html' ) );
  8.  
  9. $tags = $doc->getElementsByTagName('*'); // get all tags
  10. //print $tags->length; // count tags
  11.  
  12. // some basic handling methods ...
  13. foreach ( $tags as $i => $tag ) {
  14.  
  15. print $tag->nodeName."<br>";
  16.  
  17. if ( $tag->getAttribute('id') == 'my_id' ) {
  18. $tag->nodeValue = 'My Heading';
  19. }
  20.  
  21. if ( $tag->nodeName == 'p' ) {
  22. $tag->setAttribute('class','my_class');
  23. $tags->item($i)->setAttribute('align','center');
  24. }
  25. }
  26.  
  27. // just get first script tag
  28. $script = $doc->getElementsByTagName('script')->item(0);
  29. // a little javascript creation
  30. $script->nodeValue = <<<ENDSCRIPT
  31. alert( 'I was created by PHP Dom methods' );
  32. ENDSCRIPT;
  33.  
  34. $head = $doc->getElementsByTagName('head')->item(0);
  35. // create a new element node
  36. $style = $doc->createElement('style');
  37. $style->setAttribute('type','text/css');
  38. // attach it to head tag on page
  39. $head->appendChild($style);
  40. // give it some content
  41. $style->nodeValue = <<<ENDSTYLE
  42. body {
  43. color: indigo;
  44. }
  45. h1 {
  46. font-size: 1.29em;
  47. }
  48. p {
  49. font-family: Arial;
  50. font-style: italic;
  51. }
  52. .my_class {
  53. color: red;
  54. }
  55. ENDSTYLE;
  56.  
  57. // print out the results
  58. print $doc->saveHTML();
  59.  
  60. // or just save the container node you want
  61. //print $doc->saveXML($head);
  62.  
  63. // Complete list of DOM methods here
  64. //http://www.php.net/manual/en/class.domdocument.php
  65.  
  66. ?>

Now I will take a look and see if I can give you any feedback on the looping question.

Cheers
Last edited by langsor; Aug 19th, 2008 at 1:05 am.
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 849
Reputation: R0bb0b is on a distinguished road 
Solved Threads: 67
R0bb0b's Avatar
R0bb0b R0bb0b is offline Offline
Practically a Posting Shark

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #6
Aug 19th, 2008
Originally Posted by R0bb0b View Post
well first off you can do
t3.report_type in ('report1', 'report1', 'report1')

instead of doing a separate query for each.
that was suppose to be:
t3.report_type in ('report1', 'report2', 'report3')
“Be who you are and say what you feel because those who mind don't matter and those who matter don't mind.” - Dr. Seuss

-- The documentation is inevitable, you may get away with it for a little while but eventually you too will have to do the deed.
Reply With Quote Quick reply to this message  
Join Date: Jun 2008
Posts: 849
Reputation: R0bb0b is on a distinguished road 
Solved Threads: 67
R0bb0b's Avatar
R0bb0b R0bb0b is offline Offline
Practically a Posting Shark

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #7
Aug 19th, 2008
so basically you can condense all this:
  1. $report1 = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = 'report1'");
  2. foreach($report1 as $rpt1)
  3. {
  4. echo "$rpt1[report]"."<br>";
  5. }
  6.  
  7. $report2 = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = 'report2'");
  8. foreach($report2 as $rpt2)
  9. {
  10. echo "$rpt2[report]"."<br>";
  11. }
  12.  
  13. $report3 = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = 'report3'");
  14. foreach($report3 as $rpt3)
  15. {
  16. echo "$rpt3[report]"."<br>";
  17. }

down to this:
  1. $report1 = $db->Query("SELECT t3.report, t3.report_type FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type in('report1', 'report2', 'report3') order by t3.report_type");
  2. foreach($report1 as $rpt1)
  3. {
  4. echo "$rpt1[report]"."<br>";
  5. }
Last edited by R0bb0b; Aug 19th, 2008 at 1:20 am.
“Be who you are and say what you feel because those who mind don't matter and those who matter don't mind.” - Dr. Seuss

-- The documentation is inevitable, you may get away with it for a little while but eventually you too will have to do the deed.
Reply With Quote Quick reply to this message  
Join Date: Aug 2008
Posts: 381
Reputation: langsor is an unknown quantity at this point 
Solved Threads: 33
langsor langsor is offline Offline
Posting Whiz

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #8
Aug 19th, 2008
This is what I came up with, but I'm not positive without being able to test it -- to see where it fails ;-)

  1. <?php
  2. require_once("db.php");
  3. $db = new Database();
  4.  
  5. $report_nums = array( 'report1', 'report2', 'report3' ); // report labels
  6.  
  7. $rpthdr = $db->Query("SELECT t1.customer_id, t1.location_id, t1.location_name, t2.name FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) GROUP BY t2.customer_id, t2.location_id");
  8.  
  9. foreach( $rpthdr as $hdr ) {
  10. $customer_id = $hdr['customer_id'];
  11. $location_id = $hdr['location_id'];
  12. echo $hdr['location_name']."<br>";
  13. echo $hdr['name']."<br>";
  14.  
  15. foreach ( $report_num as $report ) {
  16.  
  17. $results = $db->Query("SELECT t3.report FROM location AS t1 Inner Join email AS t2 ON t1.customer_id = t2.customer_id AND t1.location_id = t2.location_id Inner Join report AS t3 ON t1.customer_id = t3.customer_id AND t1.location_id = t3.location_id WHERE t3.stamp >= date_sub(now(), interval 1 day) AND t1.customer_id = '$customer_id' AND t1.location_id = '$location_id' AND t3.report_type = '$report'");
  18.  
  19. foreach ( $results as $rpt ) {
  20. print $rpt['report']."<br>";
  21. }
  22. }
  23. }
  24. ?>

Let us know how it goes ...
Last edited by langsor; Aug 19th, 2008 at 1:33 am.
Reply With Quote Quick reply to this message  
Join Date: Aug 2008
Posts: 25
Reputation: Cindy2009 is an unknown quantity at this point 
Solved Threads: 0
Cindy2009 Cindy2009 is offline Offline
Light Poster

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #9
Aug 19th, 2008
Hey everyone,

Sorry it has taken me so long to reply but aparently, daniweb has some sort of function that locks you out if your emails bounce back. I have not posted to this community for some time and my email address was outdated. I updated my email address but that wasn't enough to let me back in. I registered another email address so I could come back and say thanks for the help. Now let me respond to the posts.

BTW: Cindy is my wife's name.
Last edited by Cindy2009; Aug 19th, 2008 at 1:38 am.
Reply With Quote Quick reply to this message  
Join Date: Aug 2008
Posts: 25
Reputation: Cindy2009 is an unknown quantity at this point 
Solved Threads: 0
Cindy2009 Cindy2009 is offline Offline
Light Poster

Re: Optimizing a lot of foreach loops. Please help.

 
0
  #10
Aug 19th, 2008
Originally Posted by R0bb0b View Post
well first off you can do
t3.report_type in ('report1', 'report1', 'report1')

instead of doing a separate query for each.
Rob, thanks for the help but I don't see how that will work. if i need to place all of the report1 notes under a particular heading in my template, how am I going to control that? With the seperated statements I know that I can refer to the one I need and place it exactly where I need it. Remember, there will be more than one note under report1, 2 or 3. An I wrong?
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the PHP Forum


Views: 4648 | Replies: 83
Thread Tools Search this Thread



Tag cloud for PHP
About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC