Building a task listing for a task manager I'm super new to CodeIgniter 3 and I'm using it to build a task manager (Claritask.com). Also, I'm just starting to learn how to program, so forgive me beforehand if I'm not making sense and I'll try to clarify in comments.

As I'm building my specific Project page that lists specifc tasks, I was curious to know if I'm doing it right.

What I need on my view is: tasks belonging to a specific Project &amp; the name of the project. I can get this to work fine, however I want to learn if my way of doing it correct.

I'm using two various methods

The first method I'm using, deals with having two functions on my Model, triggering two queries:

// Show project tasks
function get_tasks($project_id) {
    $this-&gt;db-&gt;from('tasks');
    $this-&gt;db-&gt;where('tasks.project_id', $project_id);
    $this-&gt;db-&gt;order_by('tasks.created_date', 'DESC');
    return $this-&gt;db-&gt;get()-&gt;result_array();    
}

// Show single project name
function get_single_project($project_id) {
    $this-&gt;db-&gt;from('projects');
    $this-&gt;db-&gt;where('projects.id', $project_id);
    return $this-&gt;db-&gt;get()-&gt;row_array();   
}


Then on my controller

$data['tasks'] = $this-&gt;project_model-&gt;get_tasks($project_id);
$data['project_name'] = $this-&gt;project_model-&gt;get_single_project($project_id)['project_name'];


This is working as expected, and producing an elegant array (especially on projects without tasks).

array (
  'tasks' =&gt; 
  array (
  ),
  'project_name' =&gt; 'Default name',
)


However I didn't like triggering two different queries, so I decided to JOIN projects with tasks and have one hit to the database, as such:

// Show project tasks
function get_project_tasks($project_id) {
    $this-&gt;db-&gt;select("tasks.*, projects.project_name");
    $this-&gt;db-&gt;from('projects');
    $this-&gt;db-&gt;where('projects.id', $project_id);
    $this-&gt;db-&gt;join('tasks', 'tasks.project_id = projects.id', "LEFT");
    $this-&gt;db-&gt;order_by('tasks.created_date', 'DESC');
    return $this-&gt;db-&gt;get()-&gt;result_array();    
}


and then my controller:

$data['tasks'] = $this-&gt;project_model-&gt;get_project_tasks($project_id);
$data['project_name'] = $data['tasks'][0]['project_name'];


While the second approach is using one query only, It's also producing an "empty" array (below) on projects without any tasks and causing to print at least one empty line within a 'foreach'.

array (
  'tasks' =&gt; 
  array (
    0 =&gt; 
    array (
      'id' =&gt; NULL,
      'project_id' =&gt; NULL,
      'list_id' =&gt; NULL,
      'task_text' =&gt; NULL,
      'task_due_date' =&gt; NULL,
      'created_by' =&gt; NULL,
      'created_date' =&gt; NULL,
      'project_name' =&gt; 'Website design',
    ),
  ),
  'project_name' =&gt; 'Website design',
)


Even though, I'm mitigating that, with the following:

&lt;?php foreach($tasks as $task) { ?&gt;
    &lt;?php if(isset($task['id'])): ?&gt;
        &lt;div&gt;&lt;?php echo $task['task_text']; ?&gt;&lt;/div&gt;
    &lt;?php endif; ?&gt;
&lt;?php } ?&gt;


Even though there are thousands of ways to skin a cat, I would like to really know which approach is the correct one: Having a specific query for each element and printing an elegant output, or optimizing the outcome.
This is really a SQL question, I'd encourage you to keep learning true SQL because it's a skill that's invaluable and it's increasingly not learnt thanks to the popularisation of noSQL solutions and abstraction heavy ORMs

To answer your question swap the direction of the query from tasks to projects instead of from projects to tasks, this will ensure you only get projects that have tasks, alternatively you could have added an extra condition in your where clause to exclude NULL tasks on the left join

or you can simply swap the left join to a normal join

$this-&gt;db-&gt;select("tasks.*, projects.project_name");
$this-&gt;db-&gt;from('tasks');
$this-&gt;db-&gt;where('projects.id', $project_id);
$this-&gt;db-&gt;join('projects', 'tasks.project_id = projects.id', "LEFT");
$this-&gt;db-&gt;order_by('tasks.created_date', 'DESC');
return $this-&gt;db-&gt;get()-&gt;result_array();