0

I have some problems with sorting datas when i try type distance for example to 5 i have this error:

 Unknown column 'dystans' in 'having clause'

 SELECT COUNT(*) AS `numrows` FROM `meet` JOIN `category` ON `category`.`id` = `meet`.`category_id` HAVING `dystans` <= '5' ORDER BY `when` ASC

Filename:    C:/xamppNew/htdocs/dzielimypasje/application/controllers/Meetings.php

Line Number: 177

Im using codeigniter. Line 177 is this

$data['count'] = $count = $this->db->count_all_results();

My controller:

$lat = $this->session->userdata('lat');
$lng = $this->session->userdata('lng');

        // To pagination
$this->load->library('pagination');
$limit = 10;
$offset = $this->uri->segment(4);

$this->db->start_cache();

    $this->db->select('*, meet.id, 
        (6731 * acos( cos( radians( '.$lat.')) * cos( radians( meet.lat)) *
   cos( radians( meet.lng) - radians( '.$lng.')) + sin( radians( '.$lat.')) *
   sin( radians( meet.lat)))) AS dystans');

         //data from search engine
    $level = $this->input->post('level');
    $cat = $this->input->post('category');
    $dystans = $this->input->post('dystans');
    $when = $this->input->post('when');

    if ($level) {
    $this->db->where('level', $level); 
    }
    if ($cat) {
    $this->db->where('category_id', $cat); 
    }
    if ($when) {
    $this->db->where('when <=', $when); 
    }
    if ($dystans) {
    $this->db->having('dystans <=', $dystans); 
    }
    $this->db->order_by('when', 'ASC');
    $this->db->from('meet');
    $this->db->join('category', 'category.id = meet.category_id');

$this->db->stop_cache();

        // count for pagination
    $data['count'] = $count = $this->db->count_all_results();

        // to pagination
    $this->db->limit($limit, $offset);

    $data['meetings'] = $this->db->get();
    $this->db->flush_cache();

    $config = some config for pagination ...

    $this->pagination->initialize($config); 

    $data['pagination'] = $this->pagination->create_links();


    $this->load->view( 'site/meetings/index' , $data );

view:

   <select type="text" name="dystans" placeholder="distance">
           <option value="">Odległość</option>
           <option value="1">Do 1 km</option>
           <option value="2">Do 2km</option>
           <option value="5">Do 5km</option>
           <option value="10">Do 10km</option>
   </select>

Any idea how to solve this ?? Propably its something with cache but im not sure, im new in this.

user3819713
  • 45
  • 1
  • 2
  • 7
  • What table is the column `dystans` in? What table is `when` in? Tell me this and I will fix your query. – whitwhoa May 13 '15 at 17:30
  • dystans is creating here: $this->db->select('*, meet.id, (6731 * acos( cos( radians( '.$lat.')) * cos( radians( meet.lat)) * cos( radians( meet.lng) - radians( '.$lng.')) + sin( radians( '.$lat.')) * sin( radians( meet.lat)))) AS dystans'); when, level, category_id from table meet – user3819713 May 13 '15 at 17:37
  • Are you wanting the fields level, category_id, when, dystans to be filterable meaning that a user could enter any of those and the query will filter down depending on how many they listed? If that is the case would any of those fields always be passed via post? Or will there only ever be only one of those fields passed? For example if a user posted level they wouldn't be able to post when? – whitwhoa May 13 '15 at 18:04
  • Yes I want to be filterable and category and level is working fine. Nowaday they are passed by post and user can sort by few fields in the same time. But later i have to figuare something becouse as you see i have pagination so if user go to next page data from post will gone so it wont be working correctly. But main problem now i dont know why i cant sort by dystans – user3819713 May 13 '15 at 18:17
  • I'm working on refactoring this. I've done all of this before. I have a posting on here somewhere explaining the pagination with filters I will link you to as well. – whitwhoa May 13 '15 at 18:36

1 Answers1

0

Alright. I dug into this and fixed everything I could find. I ditched active record for straight database access with query() function because...well...I have never liked active record and personally believe it is much much cleaner to write your query in an admin tool and copy it into your model. This gives you access to ALL of mysql's capabilities without having to jump through hoops (not to mention if you wind up using a different code base in the future you already have your queries and don't have to dig back through all of the active record code).

The main reason you were breaking at the dystans block was because you were trying to use a dynamically generated column within your where clause. The where clause only knows about columns that exist within the tables you have joined on. So to do what you are needing you have to run back through your formula.

I have also broken this out so that all of the filters will work in conjunction with one another. A user can now use filter when with filter dystans and the query will be build accordingly.

I haven't tested this code because obviously I do not have your database but it is the same way I code all of my applications. If you have trouble please let me know.

Also you should really consider breaking out your business logic or at least database interaction into a codeigniter model. Controllers should only ever act as a router between your models and views.

The link to my post on codeigniter pagination

<?php

$lat = $this->session->userdata('lat');
$lng = $this->session->userdata('lng');

// To pagination
$this->load->library('pagination');
$limit = 10;
$offset = (isset($this->uri->segment(4)) && is_numeric($this->uri->segment(4))) ? $this->uri->segment(4) : 0;

$bindArray = array();

$query = "SELECT *,"
        . " (6731 * acos(cos( radians(?)) * cos( radians( meet.lat))"
        . " * cos( radians( meet.lng) - radians(?)) + sin( radians(?))"
        . " * sin( radians( meet.lat)))) AS dystans";

$bindArray[] = $lat;
$bindArray[] = $lng;
$bindArray[] = $lat;


$query .= " FROM meet JOIN category ON category.id = meet.category_id"
        . " WHERE TRUE = TRUE";

//data from search engine
$level = $this->input->post('level');
$cat = $this->input->post('category');
$dystans = $this->input->post('dystans');
$when = $this->input->post('when');

if($level){
    $query .= " AND meet.level = ?";
    $bindArray[] = $level;
}
if($cat){
    $query .= " AND meet.category_id = ?";
    $bindArray[] = $cat;
}
if($when){
    $query .= " AND meet.when <= ?";
    $bindArray[] = $when;
}
if($dystans){
    $query .= " AND (6731 * acos(cos( radians(?)) * cos( radians( meet.lat))"
            . " * cos( radians( meet.lng) - radians(?)) + sin( radians(?))"
            . " * sin( radians( meet.lat)))) <= ?";
    $bindArray[] = $dystans;
}

$query .= "LIMIT ?,?";
$bindArray[] = $offset;
$bindArray[] = $limit;

$query_result = $this->db->query($query, $bindArray);

$data['count'] = $query_result->num_rows();
$data['meetings'] = $query_result->result();

$config = 'YOUR PAGINATION CONFIGURATION';

$this->pagination->initialize($config); 

$data['pagination'] = $this->pagination->create_links();


$this->load->view( 'site/meetings/index' , $data );
Community
  • 1
  • 1
whitwhoa
  • 2,389
  • 4
  • 30
  • 61
  • Thanks for helping. I have this error now: Error Number: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'NULL,10' at line 1 SELECT *, (6731 * acos(cos( radians(50.070215)) * cos( radians( meet.lat)) * cos( radians( meet.lng) - radians(20.045192)) + sin( radians(50.070215)) * sin( radians( meet.lat)))) AS dystans FROM meet JOIN category ON category.id = meet.category_id WHERE TRUE = TRUE LIMIT NULL,10 Filename: C:/xamppNew/htdocs/dzielimypasje/application/controllers/Meetings.php Line Number: 79 – user3819713 May 13 '15 at 19:48
  • It looks like you are not defining a default offset value. You can change the line: $offset = $this->uri->segment(4); TO $offset = (isset($this->uri->segment(4)) && is_numeric($this->uri->segment(4))) ? $this->uri->segment(4) : 0; I will update the above with the code as well. – whitwhoa May 13 '15 at 20:00
  • I have some problems, when i use your code my other functions crashes :( – user3819713 May 13 '15 at 21:06