Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I think you should do it the other way around to make it more efficient. Below i will show you the process I used to create the query. So only the final query is what you need. But I explain the steps so perhaps it will help you in the future.</p> <p>First I would select all jobs. Most likely there are a lot less jobs then users if your goal is 100.000 users.</p> <pre><code>select JOB.id, JOB.category FROM table.work JOB </code></pre> <p>Now we have all the jobs, lets see which users want to be notified about it.</p> <pre><code>select JOB.id, JOB.category, NOTIFY.user_id FROM table.work JOB LEFT JOIN table.notification_options NOTIFY ON JOB.category=NOTIFY.category WHERE NOTIFY.user_id IS NOT NULL </code></pre> <p>This creates a list with for each job, all the userID's that want to be notified about it. I added the <code>WHERE</code> clause to remove all jobs from the list nobody wants to see. Now we can <code>JOIN</code> the users table to get user details aswell. </p> <pre><code>select JOB.id , JOB.post_date , JOB.longitude , JOB.latitude , USR.user_id , USR.method_of_contact , USR.contact_frequency , USR.center_of_work_area_long , USR.center_of_work_area_lat , USR.distance_from_center , ((ACOS(SIN(USR.center_of_work_area_lat * PI() / 180) * SIN(JOB.latitude * PI() / 180) + COS(USR.center_of_work_area_lat * PI() / 180) * COS(JOB.latitude * PI() / 180) * COS((USR.center_of_work_area_long – JOB.longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS `distance` FROM table.work JOB LEFT JOIN table.notification_options NOTIFY ON JOB.category=NOTIFY.category LEFT JOIN table.user USR ON NOTIFY.user_id=USR.user_id WHERE NOTIFY.user_id IS NOT NULL HAVING `distance`&lt;=USR.distance_from_center ORDER BY USR.user_id ASC, distance ASC </code></pre> <p>I included the distance in the query. Notice that I use <code>HAVING</code> to check if the distance is smaller then the user supplied. If you would add it to the <code>WHERE</code> clause you would get an error saying <code>distance</code> is an unknown column. I also added the <code>ORDER BY</code> class to first sort it on user ID and then on distance. This will make it easier to create the array you want in PHP.</p> <p>Now there are a lot of ways to implement the daily/weekly intervals. One of them is to create seperate scripts for each interval and only select the users that set it. For example, you could create a script 'daily.php' which you run each day and have the following query</p> <pre><code>select JOB.id , JOB.post_date , JOB.longitude , JOB.latitude , USR.user_id , USR.method_of_contact , USR.contact_frequency , USR.center_of_work_area_long , USR.center_of_work_area_lat , USR.distance_from_center , ((ACOS(SIN(USR.center_of_work_area_lat * PI() / 180) * SIN(JOB.latitude * PI() / 180) + COS(USR.center_of_work_area_lat * PI() / 180) * COS(JOB.latitude * PI() / 180) * COS((USR.center_of_work_area_long – JOB.longitude) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS `distance` FROM table.work JOB LEFT JOIN table.notification_options NOTIFY ON JOB.category=NOTIFY.category LEFT JOIN table.user USR ON NOTIFY.user_id=USR.user_id WHERE NOTIFY.user_id IS NOT NULL AND USR.contact_frequency = 'daily' HAVING `distance`&lt;=USR.distance_from_center ORDER BY USR.user_id ASC, distance ASC </code></pre> <p>Now we have the query, lets create the PHP code for it. We can loop trough all the rows and create the array. Obviously instead of creating the array you could also directly process the result. Because if you create an array first, you do need to loop trough that array again afterwards.</p> <pre><code>&lt;?php $arNotify = array(); foreach ($queryresult as $row) { $userid = $row-&gt;user_id; $jobid = $row-&gt;id; //check if there is an entry for the user in the database, else create it if (!array_key_exists($userid, $arNotify)) $arNotify[$userid] = array(); //and then push the job $arNotify[$userid][] = $jobid; //the array is being created, but I still like to process the job directly //notify_user($userid, $jobid); } var_dump($arNotify); ?&gt; </code></pre> <p>There you go, the array as you want with the jobs sorted on closest first.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload