Please i need help to analyze this code . I am bit confuse to interpret what it means . This is not a code i write but some else .
All i need to do is to understand it and able to implement it
somewhere else . Thank you
$sql = "select t0.userid,concat(t3.firstname,',',t3.lastname) as name,count(*) as quizs,sum(if(t0.finalgrade > 0,1,0)) as quiz, sum(t0.finalgrade) as grade";
$sql .= " from mdl_grade_grades t0";
$sql .= " left join mdl_grade_items t1 on( t0.itemid= t1.id and t1.courseid = 37 and (t1.itemname like '%Daily Quiz%' or t1.itemname in ('Mid Term Exam','FINAL EXAM')))";
$sql .= " left join mdl_user t3 on(t3.id=t0.userid)";
$sql .= " where t0.userid >= 480";
$sql .= " group by t3.firstname,t3.lastname";
$res = mysql_query($sql);
$response->totalcount = mysql_num_rows($res);
$sql .= " Order by t3.firstname,t3.lastname";
$sql .= " Limit " .$start ."," .$limit ;
$res = mysql_query($sql);
while ($row = mysql_fetch_object($res)){
$attend = $row->gquiz / $row->quizs;
$grade = $row->grade / $row->gquiz;
$response->items[] = array('id' => $row->userid,'name' => $row->name,'attend' => $attend,'grade' => $grade);
}
//
echo json_encode($response);
The function sum(if(t0.finalgrade > 0,1,0)) actually counts the number of records having a finalgrade greater than 0.
The function sum(t0.finalgrade) simply sums the finalgrade of all records.
IF() is a builtin function and it's documented:
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL), IF() returns expr2.
Otherwise, it returns expr3.
In your case:
if(t0.finalgrade > 0,1,0)
If final grade is greater than 0 then return 1, else return 0.
Finally, SUM() sums all these zeros and ones.
PHP code does not play any role in this MySQL logic.
Related
I want top half and bottom half of data of one table I am using queries which works fine when count is even
select count(*) from reviews
select * from reviews limit count/2
select * from reviews offset count/2
but these queries fails when count is odd
kindly give any solutions
php code
public function getdatedata($data,$data1){
if(empty($data) && empty($data1) ) return false;
$data1 = $data1/2;
$empty='';
$sql = "SELECT ";
$sql .= $this->reviews.".*";
$sql .= " FROM ".$this->reviews;
$sql .= " WHERE DATE(reviews_date) = '" . $data . "' LIMIT CEIL(". $data1.")";
$result = $this->db->query($sql);
if($result->num_rows > 0){
return $result;
} else
{ return $empty ;}
}
You can use CEIL to round the result:
select count(*) from reviews
select * from reviews limit CEIL(count/2)
select * from reviews offset CEIL(count/2)
You can also use FLOOR or ROUND, whatever you like.
I used left statement and Locate to fet substring of some field in database to do (Show more). It is working properly but sometimes it's not working right.
This is the code :
function split_field($table = "d_book", $field = "bo_about", $length = 195) {
$tbl_field = "TRIM(".$table.".".$field.")";
$sql = "CONCAT(LEFT({$tbl_field}, IF(LENGTH({$tbl_field}) > {$length}, LOCATE(' ', {$tbl_field}, {$length}), {$length})),
IF(LENGTH({$tbl_field}) > {$length}, '...', ''))
AS `{$field}`";
return $sql;
}
$sql = "SELECT `bo_price`,`bo_id`, `bo_au_id`,`bo_name`,";
$sql .= split_field();
$sql .=",`bo_cover_img`, `bo_num_pages`, `d_book`.`bo_sec_id`, `d_section`.`sec_id`, `d_author`.`au_id`, `d_author`.`au_name`
FROM (`d_book`)
JOIN `d_section` ON `d_section`.`sec_id`=`d_book`.`bo_sec_id`
JOIN `d_author` ON `d_author`.`au_id`=`d_book`.`bo_au_id`
WHERE `d_book`.`bo_state` = '1'";
$sql .= " ORDER BY `d_book`.`bo_ord` DESC LIMIT $start_limit,20";
The problem is that some books that have string less than 195 don't appear totally.
Tip: all strings in arabic language
I'm trying to figure out how to build a query using Yii's CDbCriteria that would be equivalent to the following:
SELECT
*
FROM
user u
JOIN (
SELECT *
FROM skill_assessment s
WHERE s.skill = 'HTML'
AND s.score >= 80
) b ON
(u.id = b.userId)
JOIN (
SELECT *
FROM skill_assessment s
WHERE s.skill = 'CSS3'
AND s.score >= 80
) c ON
(u.id = c.userId);
etc...
Here's what I have so far, that isn't working:
$criteria = new CDbCriteria();
$criteria->alias = "u";
$criteria->select = "*";
$criteria->join = "JOIN skill_assessment s ON (u.id=s.userId)";
for($i = 0; $i < count($skill_filters); $i++) {
$criteria->addCondition("s.skill='".$skill_filters[$i]->skill."' AND s.score >= ".$skill_filters[$i]->level);
}
$users = UserModel::model()->findAll($criteria);
Any help would be greatly appreciated.
Thanks in advance.
EDIT:
I was able to build out the sql query as a string and use findAllBySql, which returned the correct UserModels that matched my search criteria, the problem is that I haven't been able to get it to return the related SkillAssessmentModels. They don't come back either with the initial query, like this:
$users = UserModel::model()->with('skill_assessments')->findAllBySql($sql);
nor if I get the results like this:
$users = UserModel::model->findAllBySql($sql);
foreach($users as $user)
{
$user->skill_assessments = $user->getRelated('skill_assessments');
}
Any thoughts on how I can get those related models?
The strange thing is that elsewhere in my application, I CAN get the related models if I do this:
$user = UserModel::model->findByPk($id);
$user->skill_assessments->getRelated('skill_assessments');
Second param for addCondition is by default 'AND'. Is this what you are looking for? May be you should define 'OR' for $operator and add braces around condition.
But in your case addCondition will by applied to the user table, not to the JOIN.
I think that this should work for you:
$criteria = new CDbCriteria();
$criteria->alias = "u";
$criteria->together= "skill_assessment";
$where = array();
for($i = 0; $i < count($skill_filters); $i++) {
$where[] = "(s.skill='".$skill_filters[$i]->skill."' AND s.score >= ".$skill_filters[$i]->level . ')';
}
$criteria->join = 'JOIN skill_assessment s ON (u.id=s.userId' . ( $where ? ( ' AND (' . join( ' OR ', $where ) . ')' ) : '') . ')';
$users = UserModel::model()->findAll($criteria);
Fetch _skill_assessment_ like this:
foreach( $users->skill_assessment as $skill_assessment )
{
echo $skill_assessment->userId;
}
At this level keep it simple:
$sql="select * from mytable where id = :id";
$cmd = Yii::app()->db->createCommand($sql)->bindParam("id", $res_id);
$cmd->execute();
Thanks a lot to Boris Belenski!
What you suggested wasn't quite what I needed, but it did get me to what I needed. Here is what I ended up with that works:
$str = "abcdefghijklmnopqrstuvwxyz";
$idxs = str_split($str);
$criteria = new CDbCriteria();
$criteria->alias = "u";
$joins = array();
for($i = 0; $i < count($skill_filters); $i++)
{
$joins[] = " JOIN (SELECT * FROM skill_assessment s WHERE s.skill = '" . $skill_filters[$i]->skill ."' AND s.score >= " . $skill_filters[$i]->level . ") " . $idxs[$i] . " ON (u.id = " . $idxs[$i] . ".userId) ";
}
$criteria->join = join(' ', $joins);
$users = UserModel::model()->findAll($criteria);
foreach($users as $user)
{
$user->skill_assessments = $user->getRelated('skill_assessments');
}
The really key part is that $joins array.
This will allow you to get all the users that match ALL the criteria for row matches in the skill_assessments table.
Also, I could probably lazily load the skill assessments in the View in a normal view, but I need to get all the skill_assessments for each user now in order to pass them back in an ajax response with the user.
Please help me to structure mysql query
I have 2 tables, #_udjacomment AND #_content
currently I have query:
$query = "SELECT udja.id";
if( $include_author == 1 ) $query .= ", udja.full_name";
if( $include_date == 1 ) $query .= ", udja.time_added";
if( $include_comment == 1 ) $query .= ", if(CHAR_LENGTH(udja.content) > ".$content_number_of_characters.", SUBSTR(udja.content, 1, ".$content_number_of_characters."), udja.content) AS content";
if( $include_link_to_comment == 1 ){
$query .= ", CASE WHEN LOCATE('com_content:', udja.comment_url) > 0
THEN CONCAT(SUBSTRING_INDEX(udja.comment_url,':',-1),'-', com_content.alias, '.html')
ELSE udja.comment_url END AS comment_url";
}
$query .= " FROM #__udjacomments AS udja, #__content AS com_content WHERE udja.is_published = 1 AND com_content.id = SUBSTRING_INDEX(udja.comment_url,':',-1) AND com_content.checked_out = 0 ORDER by udja.id DESC limit ".$number_of_comments;
But I am not getting the proper results. If I stop trying to access from the table #__content AS com_content, then I get the results for #__udjacomment AS udja correct
So, I guess I am asking how can indicate and include the constrain that I want the field com_content.alias WHERE com_content.id = SUBSTRING_INDEX(udja.comment_url,':',-1)
In some cases, udja.comment_url will have this format com_content:22, com_content:19
and in other instances, udja.comment_url will have a string like word-word-another-word
this is why I have the more extensive statement inside the conditional if($include_link_to_comment == 1)
UPDATE: THE FINAL QUERY LOOKED LIKE THIS (I IMPLEMENTED WHAT RESPONDER SUGGESTED AND CHANGED THE CASE STATEMENT AND THE WHERE STATEMENT)
$query = "SELECT udja.id";
if( $include_author == 1 ) $query .= ", udja.full_name";
if( $include_date == 1 ) $query .= ", udja.time_added";
if( $include_comment == 1 ) $query .= ", if(CHAR_LENGTH(udja.content) > ".$content_number_of_characters.", SUBSTR(udja.content, 1, ".$content_number_of_characters."), udja.content) AS content";
if( $include_link_to_comment == 1 ){
$query .= ", CASE
WHEN LOCATE('com_content:', udja.comment_url)<>0
THEN CONCAT(SUBSTRING_INDEX(udja.comment_url,':',-1),'-', com_content.alias, '.html')
ELSE udja.comment_url
END AS comment_url";
}
// THEN CONCAT(SUBSTRING_INDEX(udja.comment_url,':',-1),'-', com_content.alias, '.html')
$query .= " FROM #__udjacomments AS udja
LEFT JOIN #__content AS com_content
ON com_content.id = SUBSTRING_INDEX(udja.comment_url,':',-1)
WHERE udja.is_published = 1 ORDER by udja.id DESC limit ".$number_of_comments;
You need to use an outer join:
...
FROM #__udjacomments AS udja
LEFT JOIN #__content AS com_content
on com_content.id = SUBSTRING_INDEX(udja.comment_url,':',-1)
WHERE ...
So I have following as part of my query
SELECT * FROM $table WHERE columname LIKE '%$searchterm%'
I have tried taking out leading and/or ending wildcards meaning
SELECT * FROM $table WHERE columname LIKE '$searchterm%'
AND
SELECT * FROM $table WHERE columname LIKE '%$searchterm'
AND
SELECT * FROM $table WHERE columname LIKE '%$searchterm%' OR columname LIKE '$searchterm'
and also tried adding following to the query with no luck
OR columname = '$searchterm'
So when my search term is "myval" and if column has whole string "myval", I would like to have that selected. But ALL of my queries above, return false/return nothing where myval is searchterm and column value as full.
I can not use MATCH because this is not Full-Text index.
EDIT:
PHP Code:
$sterm = NULL;
$table = 'mytable';
if(isset($_GET['s'])) { $sterm = explode(" ", mysql_real_escape_string($_GET['s'])); }
if(isset($_POST['s'])) { $sterm = explode(" ", mysql_real_escape_string($_POST['s'])); }
if(!empty($sterm)){
$getdata = "SELECT * FROM $table WHERE termsi != 'Special' ";
foreach ($sterm as $value){
$getdata .= "AND netid_all LIKE '%$value%' OR netid_all = '$value' ";
} //End foreach
$getdata .= "LIMIT 10";
$result = mysql_query($getdata) or die(mysql_error());
$row = mysql_fetch_array($result, MYSQL_ASSOC);
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
echo <<<PRINTALL
{$row[0]}, {$row[1]}, {$row[2]}, {$row[3]}, {$row[4]}, {$row[5]}, {$row[6]}, {$row[7]}, ' <br />'
PRINTALL;
} //End While
} //End If search exists
Okay So As you guys suggested, i tried PHPMyAdmin sql console and it works fine, so it would have to be by PHP!? so here it is.
I'd suggest writing your query building like this:
$fullvalues = array();
$partials = array();
foreach ($sterm as $value){
$partials[] = "(netid_all LIKE '%" . mysql_real_escape_string($value) . "%')";
$fullvalues[] = "'" . mysql_real_escape_string($value) . "'";
}
$partials = implode(' OR ', $partials);
$fullvalues = implode(', ', $fullvalues);
$sql = <<<EOL
SELECT *
FROM $table
WHERE (termsi != 'Special')
AND (($partials) OR (netid_all IN ($fullvalues));
EOL;
Assuming your search string is a b c, you'd get this query:
SELECT *
FROM yourtable
WHERE (termsi != 'Special')
AND (((netid_all LIKE '%a%') OR (netid_all LIKE '%b%') OR (netid_all LIKE '%C%')) OR (netid_all IN ('a', 'b', 'c')))
If your search requires that all terms be present, then change the 'OR' to 'AND' in the implode.
Well found it,
$row = mysql_fetch_array($result, MYSQL_ASSOC);
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
Was the problem, earlier when I was testing things, anyhow, it should have been the following
$row = mysql_fetch_array($result, MYSQL_ASSOC);
while($row)