mysql query logic in codeigniter - php

I have two mysql tables memes and votes. Sample data is give below
Memes table
Votes table
vote = 1 is for upvote and vote = 0 is for downvote.
I want result something like this
To calculate up and down votes for each record.
Here is my code only for get records from memes table.
function loadAllMemes($categoryID,$sortby, $page,$perpage)
{
$data = array();
$this->db->select("*");
$this->db->from("memes");
$this->db->limit($perpage, $page);
if($categoryID > 0)
{
$this->db->where("categoryid",$categoryID);
}
if($sortby != "")
{
if($sortby == "recently")
{
$this->db->order_by("date","DESC");
}
else if($sortby == "popular")
{
$this->db->order_by("views","DESC");
}
}
$query = $this->db->get();
return $query->result();
}
Any help will be appreciated. Thanks

select Memes.*, sum(vote) upvote, sum(if(vote = 0, 1, 0)) downvote from memes
join vote on memes.id = memeid
group by memeid
This is not tried out. So kndly excuse if there is any syntax error
NOTE : This is purely in sql. Please do necessary things to convert for codeigneter

For Mysql you can directly put your condition us sum function and this will result a boolean 0/1 and you can use it your query as below
SELECT
m.*,
SUM(v.vote = 1) upvotes, /* this equal to SUM(CASE WHEN v.vote = 1 THEN 1 ELSE 0 END) */
SUM(v.vote = 0) downvote
FROM memes m
JOIN vote v ON m.id = v.memeid
GROUP BY m.id
For active record you can write above query as
$this->db->select('m.*,SUM(v.vote = 1) upvotes,SUM(v.vote = 0) downvote',FALSE)
->from('memes m')
->join('vote v','m.id = v.memeid ')
->group_by('m.id')
->get()
->result();

Quick solution would be by using subquery, although, I think join would be more efficient here.
SELECT
m.id,
m.title,
m.path,
m.date,
m.categoryid,
m.views,
(SELECT COUNT(*) FROM votes WHERE vote = '1' AND memeid = m.id) upvotes,
(SELECT COUNT(*) FROM votes WHERE vote = '0' AND memeid = m.id) downvotes
FROM memes m

Related

How can i join table with second table latest record

i have two table like registration table and academicdetails table and i have two records in academic table according to registration id but i want to join with latest record of academic table.
Query:
SELECT a.*, b.status AS ac_status
FROM registration AS a
LEFT JOIN academicdetails AS b ON a.id = b.registration_id
WHERE b.status = '1'
ORDER BY id DESC
LIMIT 100
PHP code:
if(isset($search['category']) && $search['category']!=''){
$condition = ', TIMESTAMPDIFF(YEAR, a.dob, CURDATE()) AS age';
}
$this->db->select('a.*,b.status as ac_status'.$condition);
$this->db->from("registration as a");
$this->db->join('academicdetails as b','a.id = b.registration_id','left');
if(isset($search['search_by_name']) && $search['search_by_name']!=''){
$this->db->where('a.name', $search['search_by_name']);
}
if(isset($search['gender']) && $search['gender']!=''){
$this->db->where('a.gender', $search['gender']);
}
if(isset($search['status']) && $search['status']!=''){
$this->db->where('b.status', $search['status']);
}
if(isset($search['category']) && $search['category']!=''){
if($search['category']=='Youth'){
$this->db->where('age>10 AND age<18');
}elseif($search['category']=='Junior'){
$this->db->where('age>17 AND age<22');
}elseif($search['category']=='Senior'){
$this->db->where('age > 21');
}
}
if(isset($search['course']) && $search['course']!=''){
$this->db->where('b.course', $search['course']);
}
$this->db->limit($search['limit'], $search['start']);
$this->db->order_by($this->id, $this->order);
$this->db->group_by('a.id');
$query = $this->db->get();
Please try following query:
SELECT * FROM `registration` LEFT JOIN academicdetails on registration.id = academicdetails.id ORDER BY academicdetails.id desc LIMIT 100;
Try this:-
$this->db->select("a.*, b.status AS ac_status");
$this->db->from('registration AS a');
$this->db->join('academicdetails AS b', 'b.registration_id = a.id', 'left');
$this->db->where("b.status",1);
$this->db->order_by("b.id","DESC");//primary key or id of your academic table.
$this->db->limit(100);
$this->db->get();

User defined variable not working in Mysql Code Igniter

I am trying to rank the rows based on when was it lasted updated partitioned by category name.
$query = "SELECT
category_name,
topic_title,
updated_ts,
#topic_rank := IF(#current_category = category_name, #topic_rank + 1, 1) AS topic_rank,
#current_category := category_name AS current_category
FROM topic_master
ORDER BY category_name, updated_ts DESC
";
$data = $this->db->query($query);
if($this->db->affected_rows() > 0)
{
return $data;
}
else
{
return false;
}
This query runs perfectly fine in MySQL and gives me the topic_rank as 1,2,3 and so on.
When I run this in CodeIgniter, I get topic_rank as 1 for all records.
What could be the issue ?
Try to use codeigniger database methods result_array():
$q = $this->db->query($query);
$data = $q->result_array();
Found an alternate way to solve this problem. No idea why the user defined variable was not working.
select category_name, topic_title as last_topic, updated_ts as last_activity, topic_pri_key as last_topic_id from
(
select
a.category_name, a.topic_title,
a.updated_ts,
a.topic_pri_key,
count(b.updated_ts)+1 as rank
from
topic_master a
left join
topic_master b
on a.updated_ts < b.updated_ts and a.category_name = b.category_name
group by 1,2,3,4
) a
where rank = 1

Count and Join did not work on phalcon framework

I have the code like this
$phql = "SELECT COUNT(a.id) FROM UserParkingIn a JOIN UserVehicle b ON a.userVehicleId = b.id WHERE b.vehicleTypeId = 1";
$result = $this->modelsManager->executeQuery($phql);
echo $result;
in UserParkingIn Table I have example id = 10, userVehicleId = 2
in UserVehicle Table I have example id =10, userVehicleId = 2, vehicleTypeId = 1
It return empty, but when I execute this query in phpMyAdmin I use this sql logic it return right number.
SELECT COUNT(a.id) FROM user_parking_in a JOIN user_vehicle b ON a.userVehicleId = b.id WHERE b.vehicleTypeId=1;
and it return number 7
Can someone explain why this return error?
Thank you.
I found the solution that id I used to count must set an alias to be like quota like this.
$query = $this->modelsManager->createQuery("SELECT COUNT(a.id) as quota FROM UserParkingIn a JOIN UserVehicle b ON a.userVehicleId = b.id WHERE a.ospoId = '$ospoId' ");
$records = $query->execute();
foreach($records as $record){
$parkingUsed = $record->quota;
}
and now it is working.

ORDER BY COUNT with condition

I have two tables, users and clients_closed_1.
I need to order the result by the count of the rows on the table client_closed_1 where meeting=1.
I did it for time_closed field but that was easy because there was no condition.
It's a part of a search code so I'll show you all of it.
With this code I manage to order it by meeting - but users who has no rows with meeting=1 isn't pull out from the database and I need them to show even if they doesn't have meetings.
if (project_type($_GET['project']) == 1) {
$table = 'clients_closed_1';
} else {
$table = 'clients_closed_2';
}
$s_query = "SELECT *,COUNT(time_closed) as numc FROM `".$table."` FULL JOIN `users` ON users.ID=user_c WHERE 1=1";
if (isset($_POST['search'])) {
if ($_POST['tm'] == 'da') {
$dd = strtotime($_POST['y']."-".$_POST['m']."-".$_POST['d']);
$s_query = $s_query." && DATE(FROM_UNIXTIME(time_closed)) = DATE(FROM_UNIXTIME(".$dd."))";
}
elseif ($_POST['tm'] == 'mon') {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=".$_POST['y']." && MONTH(FROM_UNIXTIME(time_closed))=".$_POST['m'];
}
if (!empty($_POST['search_name'])) {
$s_query = $s_query." && CONCAT(p_name,' ',l_name) LIKE '%".$_POST['search_name']."%'";
}
if (!empty($_POST['level'])) {
$query = "&& (level=3 && project IN (SELECT `project` FROM `project` WHERE type='2')) || level=4";
}
} else {
$s_query = $s_query." && YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) && MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())";
}
if (isset($_GET['order'])) {
if ($_GET['order'] == 'closing') {
$s_query = $s_query." GROUP BY users.ID ORDER BY numc DESC";
}
elseif ($_GET['order'] == 'meeting') {
$s_query = $s_query." && meeting='1' GROUP BY users.ID ORDER BY numd DESC";
}
}
$query = $db->query($s_query);
If you need any more code/doedn't understand something comment please and I'll fix it.
Thank you.
EDIT:
example of $s_query:
SELECT *,COUNT(time_closed) as numc, COUNT(meeting) as numd FROM `clients_closed_1`
FULL JOIN `users` ON users.ID=user_c WHERE 1=1 &&
YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW()) &&
MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
GROUP BY users.ID ORDER BY numc DESC
Im not sure I understand 100% of the criteria youre looking for but here is a rough draft of the query:
SELECT c.id, c.meeting, temp1.time_closed_count, temp2.meeting_count, temp3.status_count
FROM `clients_closed_1` c
FULL JOIN `users` u
ON c.user_c=u.ID
LEFT JOIN (SELECT time_closed, count(time_closed) time_closed_count FROM clients_closed_1 GROUP BY time_closed) temp1
ON c.time_closed = temp1.time_closed
LEFT JOIN (SELECT meeting, count(meeting) meeting_count FROM clients_closed_1 GROUP BY meeting) temp2
ON c.meeting = temp2.meeting
LEFT JOIN (SELECT status, count(status) status_count FROM clients_closed_1 GROUP BY status) temp3
ON c.status = temp3.status
WHERE 1=1
AND YEAR(FROM_UNIXTIME(time_closed))=YEAR(NOW())
AND MONTH(FROM_UNIXTIME(time_closed))=MONTH(NOW())
ORDER BY {$order_criteria} DESC
Whats happeneing here is, we are doing the count of all distinct meeting values in a subquery and joining it to the original query based on the value of "meeting" for each row.
This gives us the total "meetings" grouped by distinct meeting values, without cutting out rows. Such is the same for the other 2 subqueries.
This also cleans things up a bit and allows us to just insert the $order_criteria, where that could be time_closed count, meeting_count, or status_count. Just set a default (id) in case your user does not choose anything :)
Edit: Id also recommend trying to get out of the SELECT * habit. Specify the columns you need and your output will be much nicer. Its also far more efficient when you start dealing with larger tables.
After I wrote a really long query to do this I found the perfect soulution.
SELECT SUM(IF(meeting='1' && user_c=users.ID, 1,0)) as meeting_count FROM clients_closed_1 JOIN users
This query return as meeting_count the number of meeting which their value is '1'.
I didn't know I can do such thing until now, so I shared it here. I guess it can be helpull in the future.

MYSQL COUNT return NULL?

I have googled my problem but didnt get the answer.
I want to list all of the results of below sql including NULL (when COUNT(review.id) return 0 also) but instead i just got the results of articles of place that only contains review.
$sql = "SELECT tbl_place.id, tbl_place.region_id, tbl_place.subregion_id, tbl_place.title, tbl_place.metalink, tbl_place.img_thumbnail, tbl_place.summary, tbl_place.category1_id, tbl_place.category2_id, tbl_place.category3_id, COUNT(review.id) AS total_review FROM tbl_place
JOIN review ON tbl_place.id = review.place_id
WHERE
tbl_place.category1_id = '32' AND
tbl_place.status = '1' AND
review.rating != '0.00'
GROUP BY tbl_place.id
ORDER BY total_review $by
LIMIT $limit OFFSET $offset";
please use left join for review table instead of join. join is by default inner join so it will take only matched records.
the sql should be :
$sql = "SELECT tbl_place.id,
tbl_place.region_id,
tbl_place.subregion_id,
tbl_place.title,
tbl_place.metalink,
tbl_place.img_thumbnail,
tbl_place.summary,
tbl_place.category1_id,
tbl_place.category2_id,
tbl_place.category3_id,
(SELECT COUNT(*) FROM review WHERE review.rating != '0.00' AND tbl_place.id = review.place_id ) AS total_review
FROM tbl_place WHERE
tbl_place.category1_id = '32' AND
tbl_place.status = '1'
GROUP BY tbl_place.id
ORDER BY total_review $by";
it's working! thx guys!

Categories