condition in a mysql statement - php

I'm trying to write a condition in my mysql query:
SELECT g.* FROM groups AS g
JOIN users AS u
ON u.user_posts >= g.post_min
AND u.user_posts <= g.post_max
AND u.points >= g.point_min
AND u.points <= g.point_max
AND u.uid = "'.$uid.'"
how should i write a condition when the g.post_max or g.point_max equal to 0 the statement dosen't need to include max values

$sql = 'SELECT g.id,g.point_amount
FROM groups AS g
JOIN users AS u
ON u.user_posts >= g.post_min
AND (u.user_posts <= g.post_max OR (g.post_max=0 OR g.point_max=0))
AND u.points >= g.point_min
AND (u.points <= g.point_max OR (g.post_max=0 OR g.point_max=0))
AND u.uid = "'.$uid.'"
LIMIT 1';

Join them with an OR; either the skip condition is true, OR the term can't be skipped:
(g.post_max = 0) OR (u.user_posts <= g.post_max)
(g.point_max = 0) OR (u.points <= g.point_max)
EDIT: inserting it into your query:
$sql = 'SELECT g.id,g.point_amount
FROM groups AS g
JOIN users AS u
ON u.user_posts >= g.post_min
AND u.points >= g.point_min
AND ((g.post_max = 0) OR (u.user_posts <= g.post_max))
AND ((g.point_max = 0) OR (u.points <= g.point_max))
AND u.uid = "'.$uid.'"
LIMIT 1';
EDIT again: I fail at reading; misunderstood your question. This is what it should look like.

Related

How to find the Total Records of outer query

This is my query
SELECT concat(sf.from_location, "-",sf.to_location) as from_to_city,
count( *) as seach_count,
(SELECT count(DISTINCT fb.origin) as no_of_book
FROM flight_booking_details as fb
WHERE fb.status="BOOKING_CONFIRMED" and
from_code=journey_from and
to_code=journey_to AND
DATE(fb.created_datetime) >="2018-07-01" AND
DATE(fb.created_datetime) <="2018-07-04" AND
fb.journey_from = 'BLR' AND
fb.journey_to = 'DEL' ) as booking_count
FROM search_flight_history sf
WHERE DATE(sf.created_datetime) >= '2018-07-01' AND
DATE(sf.created_datetime) <= '2018-07-04' AND
(sf.from_location = 'BLR' OR
sf.from_code = 'BLR') AND
(sf.to_location = 'DEL' OR
sf.to_code = 'DEL')
GROUP BY from_code,
to_code
Here I need to find the Total Records of this query.
Please any one help me to find this one
If really just need the count of rows returned by your query, you can try the following:
select count(*)
from
(
SELECT concat(sf.from_location, "-",sf.to_location) as from_to_city,
count( *) as seach_count,
(SELECT count(DISTINCT fb.origin) as no_of_book
FROM flight_booking_details as fb
WHERE fb.status="BOOKING_CONFIRMED" and
from_code=journey_from and
to_code=journey_to AND
DATE(fb.created_datetime) >="2018-07-01" AND
DATE(fb.created_datetime) <="2018-07-04" AND
fb.journey_from = 'BLR' AND
fb.journey_to = 'DEL' ) as booking_count
FROM search_flight_history sf
WHERE DATE(sf.created_datetime) >= '2018-07-01' AND
DATE(sf.created_datetime) <= '2018-07-04' AND
(sf.from_location = 'BLR' OR
sf.from_code = 'BLR') AND
(sf.to_location = 'DEL' OR
sf.to_code = 'DEL')
GROUP BY from_code,
to_code
) X;

how to combine two queries to produce one result in codigniter

this is my query working fine
$offset = ($this->uri->segment(4))?$this->uri->segment(4):0;
$limit =10;
i donn't use $user_id becoz this function uses pagination
$q = "select distinct attandence.user_id ,monthname(date), sum(is_absent) as absents,in_time,out_time , count(date) as working_days, leave_type , users.f_name ,leave_types.type ,leave_types.leave_type_id , users.l_name ,( select count(leave_type) from attandence where leave_type != 0 and user_id = 4 and month(date) = 10 ) as leave_count from attandence join users on (users.user_id = attandence.user_id) left join leave_types on(leave_types.leave_type_id = attandence.leave_type) where in_time != '' and out_time != '' ".$where_condition." GROUP BY attandence.user_id LIMIT ".$limit." OFFSET ". $offset;
$rows = $this->attandence_model->q($q);
$this->data['Details'] = $rows;
in view i just passed
<? foreach ($Details as $detail){ ?>
<? } ?>
Any help is going to be appreciated. :)
I have solution your query you can add sub query Sub query
See Example:
$q = "select distinct attandence.user_id ,monthname(date), sum(is_absent) as absents,in_time,out_time , count(date) as working_days, leave_type , users.f_name ,leave_types.type ,leave_types.leave_type_id , users.l_name, (select count(leave_type) from attandence where leave_type != 0 and user_id = 15 and month(date) = 10) as leave_count from attandence join users on (users.user_id = attandence.user_id) left join leave_types on(leave_types.leave_type_id = attandence.leave_type) where in_time != '' and out_time != '' ".$where_condition." GROUP BY attandence.user_id LIMIT ".$limit." OFFSET ". $offset;

Adding condition to mysql query and fetch again

I have 3 queries which I run which are nearly identical, the latter two have an AND condition.
Main query:
$mess = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ?
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess->bind_param("i", $room);
$mess->execute();
$mess->store_result();
$mess->bind_result($chatid,$chat_userid,$message,$voteup,$votedown,$date);
while($row = $mess->fetch()){
//im fetching here in my <div class='div1' >
}
Then, in the second div I have to add an AND condition:
$mess2 = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ? AND voteup - votedown >= 5
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess2->bind_param("i", $room);
$mess2->execute();
$mess2->store_result();
$mess2->bind_result($chatid,$chat_userid,$message,$voteup,$votedown,$date);
while($row2 = $mess2->fetch()){
//im fetching here in my <div class='div2' >
}
Lastly, in the third div I have a slightly different AND condition:
$mess3 = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ? AND votedown - voteup >= 5
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess3->bind_param("i", $room);
$mess3->execute();
$mess3->store_result();
$mess3->bind_result($chatid,$chat_userid,$message,$voteup,$votedown,$date);
while($row3 = $mess3->fetch()){
//im fetching here in my <div class='div3' >
}
Everything works BUT doing this near-same query seems clumsy. Is it possible to construct the same thing with only one query? I have used $mess->data_seek(0); but its not helping because I didn't add my condition to the query.
Just go for PhP to filter your data instead of triple query your database. In this case you can figure out to go for this solution because you call 3 times your query with the same parameter :
$mess3 = $mysqli->prepare(" SELECT *
FROM ( SELECT cm.id ,
cm.userid,
cm.message,
cm.voteup,
cm.votedown,
cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ?
AND votedown - voteup >= 5
ORDER BY cm.date DESC LIMIT 30 ) ddd
ORDER BY date ASC ");
$mess3->bind_param("i", $room);
$mess3->execute();
$mess3->store_result();
$mess3->bind_result($chatid,$chat_userid ,$message,$voteup,$votedown ,$date);
while($row = $mess3->fetch()){
$voteup = $row['voteup'];
$votedown = $row['votedown'];
addToDiv1($row);
if( $voteup - $votedown >= 5 ) {
addToDiv2($row);
}
if( $votedown - $voteup >= 5 ) {
addToDiv3($row);
}
}
I will just give an answer based specifically on cleaning up your code. Technically you will still make the 3 calls in this scenario, but it will be cleaner because you include one function only, you don't see the script behind it.
As I mentioned, I am not an SQL aficionado so I can not give a good solution there (maybe you can use GROUP BY and perhaps an OR clause...I don't really know...). If I were to do this, I would do a function that can return all the options:
/core/functions/getChatMessages.php
function getChatMessages($settings,$mysqli)
{
$id = (!empty($settings['id']))? $settings['id'] : false;
$type = (!empty($settings['type']))? $settings['type'] : false;
$max = (!empty($settings['max']))? $settings['max'] : 30;
$mod = '';
// No id, just stop
if(!is_numeric($id))
return false;
// equation one
if($type == 'up')
$mod = ' AND voteup - votedown >= 5';
// equation two
elseif($type == 'down')
$mod = ' AND votedown - voteup >= 5';
$mess = $mysqli->prepare("SELECT * from ( SELECT cm.id ,cm.userid,cm.message,cm.voteup,cm.votedown,cm.date
FROM chat_messages cm
INNER JOIN members m ON m.id =cm.userid
INNER JOIN chat_settings cs ON cs.id = cm.room_id
WHERE cm.setting_id = ? {$mod}
ORDER BY cm.date DESC LIMIT {$max} ) ddd
ORDER BY date ASC");
$mess->bind_param("i", $id);
$mess->execute();
$mess->store_result();
$mess->bind_result($chatid, $chat_userid, $message, $voteup, $votedown, $date);
while($mess->fetch()){
$result[] = array(
'chatid'=>$chatid,
'chat_userid'=>$chat_userid,
'message'=>$message,
'voteup'=>$voteup,
'votedown'=>$votedown
);
}
// Send back the data
return (!empty($result))? $result : array();
}
To use:
// Include our handy function
require_once('/core/functions/getChatMessages.php');
// Store our id for use
$settings['id'] = 100;
// Should get 30 from first select
$voteGen = getChatMessages($settings,$mysqli);
// Should get 30 from second select
$settings['type'] = 'up';
$voteUp = getChatMessages($settings,$mysqli);
// Should get 15 from third select
// Just for the heck of it, I added in a limit settings
$settings['max'] = 15;
$settings['type'] = 'down';
$voteDown = getChatMessages($settings,$mysqli);
Now that you have these stored, just use a foreach loop to place them into your view. The good side of this is that you can call this where ever and when ever since the function only returns data. It allows you to work with the data in a view or non-view situation. Side note, I use PDO, so if there is something ineffective with the way the mysqli is fetching, that will be why. It's probably just best to fetch an assoc array to return...

Too heavy query execution

I have a Database with 187840 lines .
When i execute this query i have this message Query execution was interrupted
TOO HEAVY QUERY
SELECT days.day,count(U.sig_name) as number
FROM days
LEFT JOIN linked U ON
days.day = date(timestamp)
AND
U.sig_name REGEXP "^Tester"
GROUP BY days.day;
What is th solution ?
This is your query:
select days.day, count(U.sig_name) as number
from days left join
linked U
on days.day = date(timestamp) AND U.sig_name REGEXP "^Tester"
group by days.day;
You have a problem because of the function call around timestamp. You might find this version better:
select days.day,
(select count(*)
from linked u
where u.timestamp >= days.day an du.timestamp < date_add(days.day, interval 1 day) and
u.sig_name not like '%Tester%'
)
from days;
For performance, you want a composite index on linked(timestamp, sig_name). This eliminates the outer aggregation (the aggregation uses the index instead), and allows an index to be used for the matching.
You can handle massive data using LIMIT:
$limit_size = 10000;
$flag_done = false;
for ($i = 1; ! $flag_done; $i++) {
$queryString = "SELECT days.day,count(U.sig_name) as number from days left join linked U on days.day = date(timestamp) AND U.sig_name REGEXP "^Tester" group by days.day LIMIT $index*$limit_size, $limit_size";
if($result = mysql_query($queryString, $db)){
[WHAT YOU WANT TO DO WITH RESULT HERE]
} else $flag_done = true;
}

mysql query logic in codeigniter

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

Categories