I want to get most view by query:
$this->db->select("a.pid, a.title, a.pic, a.date_created, d.view as post_view");
$this->db->from("posts as a");
$this->db->join('views as d', 'd.post_id=a.pid');
$this->db->join('cats as b', 'b.catid=a.catid'); //ensure Cat existed
$this->db->where("a.block", 0);
$this->db->order_by("d.view", "desc");
$this->db->limit(5);
$query = $this->db->get();
return $query->result();
but always automatically add order_by pid asc. and never order desc for d.view field. i try to print query string and here:
SELECT `a`.`pid`, `a`.`title`, `a`.`pic`, `a`.`date_created`, `d`.`view` as `post_view` FROM `posts` as `a` JOIN `views` as `d` ON `d`.`post_id`=`a`.`pid` JOIN `cats` as `b` ON `b`.`catid`=`a`.`catid` WHERE `a`.`block` =0 ORDER BY `pid` asc, `d`.`view` DESC LIMIT 5
Any suggestion to fix? (CI version 3.*)
Related
I have 2 tables, I want to display all user in list in my web, and show his last login details from table tbl_login_details but get the last login details for this user
1- diplay all my user from table - tbl_user
2- display LAST login for all user so the data of tbl_login_details must be ORDER then take THE LIMT
---------tbl_user-------
id user_id user_name
1 5 mohammed
2 7 ahmed
-------------tbl_login_details----------
id user_id last_activity
1 7 2016-5-2
2 7 2017-4-2
3 7 20-17-8-4
My Work is
$this->db->select('m.*,u.*');
$this->db->from('tbl_user m');
//$this->db->where("m.user_id", $id);
$this->db->join('tbl_login_details u ', 'u.user_id = m.user_id');
$where = 'm.user_id = u.user_id OR u.user_id = m.user_id OR m.user_id=" " ORDER last_activity';
$where = $this->db->order_by("last_activity", "desc");
$this->db->where($where);
// $this->db->limit('1');
$this->db->group_by('m.user_id');// add group_by
$query = $this->db->get();
return $query->result();
use max aggregation to find the last activity:
select userid, max(last_activity)
from tbl_user a inner join tbl_login_details b on a.userid=b.userid
are you try to get the last detail login from each user, If yes you can using ORDER DESC AND LIMIT 1
create query for display tbl_user first
SELECT * FROM tbl_user ORDER BY id ASC
then you can create query for get last user login
SELECT * FROM tbl_login_details WHERE user_id = 7 ORDER BY id DESC LIMIT 1
you can using modal pop up for display detail login.
or are you try display like this ?
id user_id user_name last_activity
1 5 mohammed 20-17-8-4
2 7 ahmed 20-17-8-4
help into CI max aggregation to find the last activity:
$query = $this->db->query("select userid, max(last_activity) from tbl_user a inner join tbl_login_details b on a.userid=b.userid");
foreach ($query->result() as $row)
{
echo $row->title;
echo $row->name;
echo $row->body;
}
Here is the simple SQL code to fetch that. You can do it CodeIgniter's way:
Implement this SQL into CodeIgniter.
SELECT tbl_user.user_id, tbl_user.user_name, tbl_login_details.user_id, tbl_login_details.last_activity FROM tbl_user, tbl_login_details WHERE tbl_user.user_id = tbl_login_details.user_id ORDER BY tbl_login_details.last_activity DESC
May be you are searching for Following
SELECT user_id, user_name, (SELECT last_activity FROM tbl_login_details WHERE tbl_login_details.user_id = tbl_user.user_id ORDER BY last_activity DESC LIMIT 1) as last_activity FROM tbl_user
updated code. search for how to write this sub query in active record. or just use custom query like $query = $this->db->query("YOUR QUERY");
Hope this can help you
SELECT u.id,u.user_id,u.user_name,MAX(l.last_activity) AS last_activity
FROM tbl_user u
LEFT JOIN tbl_login_details l ON(u.user_id=l.user_id)
GROUP BY u.user_id
on codeigniter custom query builder
$query = $this->db->query("SELECT u.id,u.user_id,u.user_name,MAX(l.last_activity) AS last_activity FROM tbl_user u LEFT JOIN tbl_login_details l ON(u.user_id=l.user_id) GROUP BY u.user_id");
foreach ($query->result() as $row)
{
echo $row->id;
echo $row->user_id;
echo $row->user_name;
echo $row->last_activity ;
}
I would like to make a query by an aggregated value from the model relations.
As example I should get only Posts which has the last comment between two dates.
SELECT posts.*, MAX(comments.created_at)
as max FROM posts
JOIN comments ON (comments.post_id = posts.id)
GROUP BY posts.id HAVING max > '2014-01-01 00:00:00' AND max < '2014-02-01 00:00:00'
Instead of joins use builtin methods:
// Assuming you have relations setup
Post::whereHas('comments', function ($q) use ($from, $till) {
$q->groupBy('post_id')
->havingRaw("max(created_at) between '{$from}' and '{$till}'");
})->get();
It will produce:
select * from `posts` where
(select count(*) from `comments` where `comments`.`post_id` = `posts`.`id`
group by `post_id`
having max(created_at) between '2014-01-01' and '2014-02-01'
) >= 1 limit 1
i have 4 tables jobs, company, employment_type & job_category the primary key for each are job_id, com_id, type_id, job_cat_id, but (com_id, type_id, job_cat_id) are foreign key to jobs table.
my query without active record work perfectly and it is as follow
select company.com_id, company.company_name, jobs.job_id, jobs.title, jobs.opening_date, jobs.closing_date, jobs.number_of_pos, employment_type.type_id, employment_type.type, job_category.job_cat_id, job_category. category from company inner join jobs on company.com_id=jobs.com_id inner join employment_type on employment_type.type_id=jobs.type_id inner join job_category on job_category.job_cat_id=jobs.job_cat_id
but if i try to use codeiginiter active record such as
$this->db->select('company.com_id, company.company_name, jobs.job_id, jobs.title, jobs.opening_date, jobs.closing_date, jobs.number_of_pos, employment_type.type_id, employment_type.type, job_category.job_cat_id, job_category. category');
$this->db->from('company');
$this->db->join('jobs','company.com_id=jobs.com_id','inner');
$this->db->join('employment_type', 'employment_type.type_id=jobs.type_id','inner');
$this->db->join('job_category', 'job_category.job_cat_id=jobs.job_cat_id','inner');
$this->db->order_by('job_id','DESC');
$this->db->limit($limit, $offset);
$query = $this->db->get();
return $query->result_array();
i end up with the following error
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 '`) INNER JOIN `jobs` ON `company`.`com_id`=`jobs`.`com_id` INNER JOIN `employmen' at line 1
SELECT `company`.`com_id`, `company`.`company_name`, `jobs`.`job_id`, `jobs`.`title`, `jobs`.`opening_date`, `jobs`.`closing_date`, `jobs`.`number_of_pos`, `employment_type`.`type_id`, `employment_type`.`type`, `job_category`.`job_cat_id`, `job_category`.` category FROM (`company`) INNER JOIN `jobs` ON `company`.`com_id`=`jobs`.`com_id` INNER JOIN `employment_type` ON `employment_type`.`type_id`=`jobs`.`type_id` INNER JOIN `job_category` ON `job_category`.`job_cat_id`=`jobs`.`job_cat_id` ORDER BY `job_id` DESC LIMIT 10
Any help would be appreciated
you have a space in job_category. category remove that and you should be golden
Format your query like this
$data = array(
'company.com_id',
'company.company_name',
'jobs.job_id',
'jobs.title',
'jobs.opening_date',
'jobs.closing_date',
'jobs.number_of_pos',
'employment_type.type_id',
'employment_type.type',
'job_category.job_cat_id',
'job_category.category'
);
$this->db->select($data);
$this->db->from('company');
$this->db->join('jobs','company.com_id=jobs.com_id','inner');
$this->db->join('employment_type', 'employment_type.type_id=jobs.type_id','inner');
$this->db->join('job_category', 'job_category.job_cat_id=jobs.job_cat_id','inner');
$this->db->order_by('job_id','DESC');
$this->db->limit($limit, $offset);
$query = $this->db->get();
return $query->result_array();
How can I write the following query in Codeigniter style.
SELECT COUNT(`id`) AS reccount
FROM
(SELECT `id` FROM table1
WHERE tid= '101' AND `status` = 1
UNION ALL
SELECT `id` FROM table2
WHERE tid= '101' AND `status` = 1
UNION ALL
SELECT `id` FROM table3
WHERE tid= '101' AND `status` = 1) t
I have used the following way to execute it.
Is it the only correct way or do you have any suggestion to improve it?
$q = $this->db->query(SELECT COUNT(`id`) AS reccount
FROM
(SELECT `id` FROM table1
WHERE tid= '101' AND `status` = 1
UNION ALL
SELECT `id` FROM table2
WHERE tid= '101' AND `status` = 1
UNION ALL
SELECT `id` FROM table3
WHERE tid= '101' AND `status` = 1) t ");
Since CodeIgniter 3 it's been introduced in Active Record the function get_compiled_select() that gives the query string without actually executing the query.
This allows #MDeSilva method to use less resources, being adapted as follows:
function get_merged_result($ids){
$this->db->select("column");
$this->db->distinct();
$this->db->from("table_name");
$this->db->where_in("id",$model_ids);
$query1 = $this->db->get_compiled_select(); // It resets the query just like a get()
$this->db->select("column2 as column");
$this->db->distinct();
$this->db->from("table_name");
$this->db->where_in("id",$model_ids);
$query2 = $this->db->get_compiled_select();
$query = $this->db->query($query1." UNION ".$query2);
return $query->result();
}
You can use CI to generate a union query. However, latest versions made this much harder than before.
DB has a method called _compile_select, in previous versions of CI it was public, however now it is protected so you can't just call $this->db->_compile_select() from your controller. In order to do this properly one could:
Create custom loader class to be able to extend core/database classes (i.e. load MY_DB_active_record instead of CI_DB_active_record).
Create custom activerecord class, with just one method:
public function compile_select() {
return $this->_compile_select();
}
In your controller, create all necessary queries, compile them into a string array using our public method compile_select()
Join the array into single query: '(' . implode(') UNION (', $queries) . ')'. You can also wrap this into a separate method inside your custom AR class.
function get_merged_result($ids){
$this->db->select("column");
$this->db->distinct();
$this->db->from("table_name");
$this->db->where_in("id",$model_ids);
$this->db->get();
$query1 = $this->db->last_query();
$this->db->select("column2 as column");
$this->db->distinct();
$this->db->from("table_name");
$this->db->where_in("id",$model_ids);
$this->db->get();
$query2 = $this->db->last_query();
$query = $this->db->query($query1." UNION ".$query2);
return $query->result();
}
I'm needeing to get all the child categories from the given to use in a where_in with active records of codeigniter.
The problem is that the second query get mixed with the main one breaking it completely.
Main Query
$this->db->select('artworks.*, users.id as owner, users.name as user_name');
$this->db->from('artworks');
$this->db->join('users', 'users.id = artworks.user_id');
$category = $this->get_child_categories($this->get_categories(), $matches[1]);
$this->db->where_in('artworks.category', $this->category['child']);
$this->db->group_by('artworks.id');
$query = $this->db->get();
return $query->result_array();
Second Query "get_categories()"
$this->db->select('*');
$this->db->order_by('parent', 'asc');
$this->db->order_by('name', 'asc');
$query = $this->db->get('categories');
return $query->result_array();
get_child_categories
function get_child_categories($categories, $parent){
foreach($categories as $category){
if($category['parent'] == $parent){
array_push($this->category['childs'], $category['id']);
$this->get_child_categories($categories, $category['id']);
}
}
}
But i'm getting this error where clearly displays that the second query is quetting inside the main one.
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 '* FROM (`artworks`, `categories`) JOIN `users` ON `users`.`id` = `artworks`.`use' at line 1
SELECT `artworks`.*, `users`.`id` as user_id, `users`.`name` as user_name, * FROM (`artworks`, `categories`) JOIN `users` ON `users`.`id` = `artworks`.`user_id` WHERE `artworks`.`rating` IN ('g', 'm', 'a') ORDER BY `artworks`.`id` desc, `parent` asc, `name` asc
Filename: D:\Server\htdocs\gallery\system\database\DB_driver.php
Line Number: 330
I personally think this is an error in CodeIgniter's Active Record approach, if it's supposed to follow the Active Record pattern at all. It should totally enforce either one of these:
queries contained in a single data context
queries specified in a atomic instruction
As neither of these is happening, at the moment you're unwillingly mixing two queries with a structure that CodeIgniter does not support, thus creating that invalid query.
For a simple solution, I would suggest for you to invert the order of the instructions so that the queries are executed separately.
$category = $this->get_child_categories($this->get_categories(), $matches[1]);
# the first query gets executed here, your data context is cleaned up
$this->db->select('artworks.*, users.id as owner, users.name as user_name');
$this->db->from('artworks');
$this->db->join('users', 'users.id = artworks.user_id');
$this->db->where_in('artworks.category', $this->category['child']);
$this->db->group_by('artworks.id');
$query = $this->db->get();
# your second query gets executed here
return $query->result_array();