Database Query - Order by two values (Nested Order) - mysql

I want to order results by two database values: rating_full followed by rating_count
Currently, Im ordering by the highest rating_full. it works fine.
$sql .= " LEFT JOIN {$wpdb->postmeta} rating ON ({$wpdb->posts}.ID = rating.post_id AND rating.meta_key IN ('rating_full'))";
…
…
$sql = "cast(rating.meta_value as decimal(10,2)) {$order}";
……
The first line of code, part of the SELECT statement, retrieves the rating_full part
The second line of code is the ORDER BY part, which currently just uses the rating_count
As far as I can tell rating.meta_value referred to in the second line of code is the rating_full value
I'm trying to get it to ORDER BY rating_full, rating_count
I'm not sure how to modify the first line so that I can achieve this.
Thanks
FULL CODE:
<?php
// Sorting
add_filter('posts_join', 'directorySortingJoin',10,2);
function directorySortingJoin($join, $query) {
global $wpdb, $aThemeOptions;
if ($query->is_main_query() && !$query->is_admin && ((isset($_GET['dir-search'])) || (isset($query->query_vars["a-dir-item-category"])) || (isset($query->query_vars["a-dir-item-location"])))) {
$sql = "";
// default ordering
$orderby = (isset($aThemeOptions->directory->defaultOrderby)) ? $aThemeOptions->directory->defaultOrderby : 'post_date';
// get from get parameters
if (!empty($_GET['orderby'])) {
$orderby = $_GET['orderby'];
}
if ($orderby == 'rating') {
$sql .= " LEFT JOIN {$wpdb->postmeta} rating ON ({$wpdb->posts}.ID = rating.post_id AND rating.meta_key IN ('rating_full'))";
//$sql .= " LEFT JOIN {$wpdb->postmeta} rating ON (wp_posts.ID = rating.post_id AND rating.meta_key IN ('rating_full')) LEFT JOIN {$wpdb->postmeta} count ON ({$wpdb->posts} = count.post_id AND count.meta_key IN ('rating_count'))";
}
if ($orderby == 'packages') {
directorySaveUserPackagesToDb();
$sql .= " LEFT JOIN {$wpdb->usermeta} packages ON ({$wpdb->posts}.post_author = packages.user_id AND packages.meta_key IN ('dir_package'))";
}
if (isset($aThemeOptions->directory->showFeaturedItemsFirst)) {
$sql .= " LEFT JOIN {$wpdb->postmeta} featured ON ({$wpdb->posts}.ID = featured.post_id AND featured.meta_key IN ('dir_featured'))";
}
$join .= $sql;
//echo $join;
}
return $join;
}
add_filter('posts_orderby', 'directorySortingOrderby',10,2);
function directorySortingOrderby($orderby, $query) {
global $wpdb, $aThemeOptions;
if ($query->is_main_query() && !$query->is_admin && ((isset($_GET['dir-search'])) || (isset($query->query_vars["a-dir-item-category"])) || (isset($query->query_vars["a-dir-item-location"])))) {
$sql = "";
// default ordering
$orderby = (isset($aThemeOptions->directory->defaultOrderby)) ? $aThemeOptions->directory->defaultOrderby : 'post_date';
$order = (isset($aThemeOptions->directory->defaultOrder)) ? $aThemeOptions->directory->defaultOrder : 'DESC';
// get from get parameters
if (!empty($_GET['orderby'])) {
$orderby = $_GET['orderby'];
}
if (!empty($_GET['order'])) {
$order = $_GET['order'];
}
if ($orderby == 'rating') {
if (isset($aThemeOptions->directory->showFeaturedItemsFirst)) {
$sql = "featured.meta_value DESC, convert(rating.meta_value, decimal) {$order}";
} else {
//$sql = "convert(rating.meta_value, decimal) {$order}";
$sql = "cast(rating.meta_value as decimal(10,2)) {$order}";
//$sql = "cast(rating.meta_value as decimal(10,2)) {$order}, count.meta_value {$order}";
}
} else if ($orderby == 'packages') {
if (isset($aThemeOptions->directory->showFeaturedItemsFirst)) {
$sql = "featured.meta_value DESC, packages.meta_value {$order}";
} else {
$sql = "packages.meta_value {$order}";
}
} else {
if (isset($aThemeOptions->directory->showFeaturedItemsFirst)) {
$sql = "featured.meta_value DESC, {$wpdb->posts}.{$orderby} {$order}";
}
}
$orderby = $sql;
//echo $orderby;
}
return $orderby;
}
// Save directory packages for sorting
function directorySaveUserPackagesToDb() {
$users = get_users();
// capabilities list
$roles = array(
'administrator' => 10,
'directory_5' => 9,
'directory_4' => 8,
'directory_3' => 7,
'directory_2' => 6,
'directory_1' => 5,
'editor' => 4,
'author' => 3,
'contributor' => 2,
'subscriber' => 1
);
foreach ($users as $user) {
if (isset($user->roles[0])) {
if (array_key_exists($user->roles[0], $roles)) {
update_user_meta($user->ID, 'dir_package', $roles[$user->roles[0]]);
} else {
update_user_meta($user->ID, 'dir_package', 0);
}
}
}
}

The MySQL documentation for ORDER BY should be helpful here, particularly the last paragraph on sorting multiple columns.
Your ORDER BY should be something like
ORDER BY rating_full DESC, rating_count DESC

Related

How to use SQL and PHP multiple criteria?

If my original code like this
if (!isset($_GET['page'])) {
$page = 1;
} else {
$page = $_GET['page'];
}
if (!isset($_GET['urut'])) {
$urut = "" ;
} else {
$urut = $_GET['urut'];
}
if($urut == 0){ $urutkan = "id DESC"; };
if($urut == 1){ $urutkan = "harga ASC"; };
if($urut == 2){ $urutkan = "harga DESC"; };
if (!isset($_GET['jenis'])) {
$jenis = [] ;
} else {
$jenis = $_GET['jenis'];
}
if (!isset($_GET['kategori'])) {
$kategori = [] ;
} else {
$kategori = $_GET['kategori'];
}
if (!isset($_GET['wilayah'])) {
$wilayah = [];
} else {
$wilayah = $_GET['wilayah'];
}
$results_per_page = 10;
$sql = "SELECT * FROM item ";
$result = mysqli_query($link, $sql);
$number_of_results = mysqli_num_rows($result);
$number_of_pages = ceil($number_of_results/$results_per_page);
$first_page = ($number_of_results/$number_of_results);
$last_page = $number_of_pages;
$this_page_first_result = ($page-1)*$results_per_page;
$previous = ($page-1);
$next = ($page+1);
$sql='SELECT * FROM item LIMIT ' . $this_page_first_result . ',' . $results_per_page ;
$result = mysqli_query($link, $sql);
What is the right syntax if i want the output like this
$sql='SELECT * FROM item WHERE jenis LIKE '$jenis' AND kategori LIKE '$kategori' AND wilayah LIKE '$wilayah' ORDER BY '$urutkan' LIMIT ' . $this_page_first_result . ',' . $results_per_page ;
Thx for help
...............................................................................................................................................................................................................................................................................................................................
For use multiple criteria into MySQL query you have to use AND operator in query.
Below i give an sample to use criteria with LIKE clause.
SELECT * FROM item WHERE jenis LIKE '%'.$jenis.'%' AND kategori LIKE '%'.$kategori.'%' AND wilayah LIKE '%'.$wilayah.'%' ORDER BY $urutkan
LIMIT $this_page_first_result . ',' . $results_per_page

Perl Update array

I am getting data back from a database query but I need to update an array.
sub get_query_data{
my ($self, $user_id) = #_;
my $sql_query = "Select * from table";
my ( $returndata ) = $self->_exec_and_fetch_all( $sql );
for ( #$returndata ) {
push( #$_, 'replace me' );
}
return $returndata;
}
How do I replace the third element when I am looping through the data?
There is data coming back from the query but he above is not working.
If $self->_exec_and_fetch_all can return undef,
my $rows = $self->_exec_and_fetch_all($sql);
if ($rows) {
for my $row (#$rows) {
$row->[2] = 'replaceme';
}
}
return $rows;
Otherwise,
my $rows = $self->_exec_and_fetch_all($sql);
for my $row (#$rows) {
$row->[2] = 'replaceme';
}
return $rows;
or
my $rows = $self->_exec_and_fetch_all($sql);
$_->[2] = 'replaceme' for #$rows;
return $rows;

mysqli_free_result - select successful, but still getting warning

I have a problem whereby I am running a SELECT query that returns a valid result set. I process the results using mysqli_fetch_assoc and then pass the result set to mysqli_free_result, which returns false. I have done a var_dump of the result before and after the call to confirm it is a valid result (seems to be to me - I can access the data I expect to). The query I am running is something like:
select us.user_session_key
, u.user_key
, ut.code as user_type
from t_user u
inner join t_user_type ut on u.user_type_key = ut.user_type_key
inner join t_user_session us
on u.user_key = us.user_key
where u.email = 'tim.super#en.com'
and us.session_id = 'mjsvu6fru3dtfk1bbs59fc8t20'
and us.expired_yn = 'N'
order by 1 desc
Var dump of the result object:
object(mysqli_result)#2 (5) {
["current_field"]=>
int(0)
["field_count"]=>
int(3)
["lengths"]=>
NULL
["num_rows"]=>
int(1)
["type"]=>
int(0)
}
I am using similar to the following code to process query/result:
$result = mysqli_query ( $conn, $sql );
if ($result) {
var_dump($result);
if (preg_match('/^[[:space:]]*select/i', $sql) == 1) {
while ($row = mysqli_fetch_assoc ( $result )) {
$return_val[sizeof($return_val)] = $row;
}
if (!clear_results($result)) {
print "error: ".$sql;
}
}
} else {
http_response_code(401);
print $sql . "\n";
print mysqli_error($conn);
die("error");
}
function clear_results($result) {
global $conn;
if ($result) {
if (!mysqli_free_result ( $result )) {
return false;
}
}
while (mysqli_more_results($conn)) {
mysqli_next_result($conn);
mysqli_free_result(mysqli_store_result($conn));
}
return true;
}

query with parentheses in zend framework 2.2

I want my query like this:
SELECT tbl_bids. * , tbl_department.vDeptName, tbl_user.vFirst
FROM tbl_bids
LEFT JOIN tbl_bids_department ON tbl_bids_department.iBidID = tbl_bids.iBidID
LEFT JOIN tbl_department ON tbl_department.iDepartmentID = tbl_bids_department.iDepartmentID
LEFT JOIN tbl_user ON tbl_user.iUserID = tbl_bids.iUserID
WHERE tbl_user.iUserID = '1' // with parantheses in where clause
AND (
tbl_department.vDeptName = 'PHP'
OR tbl_department.vDeptName = 'android'
)
GROUP BY tbl_bids.iBidID
ORDER BY iBidID DESC
LIMIT 0 , 30
But i can't find the way to get parantheses in my query,there are mutiple condition and loop will be there to make where clause..
here is my code
$select = $this->tableGateway->getSql()->select();
$select->columns(array('*'))
->join('tbl_bids_department', 'tbl_bids_department.iBidID = tbl_bids.iBidID', array(),"LEFT")
->join('tbl_department', 'tbl_department.iDepartmentID = tbl_bids_department.iDepartmentID',array(tbl_department.vDeptName),"LEFT")
->join('tbl_user', 'tbl_user.iUserID = tbl_bids.iUserID',array(tbl_user),"LEFT")
->group('tbl_bids.iBidID');
$where = new \Zend\Db\Sql\Where();
$where->equalTo( 'tbl_bids.eDeleted', '0' );
$sWhere = new \Zend\Db\Sql\Where();
for ( $i=0 ; $i<count($aColumns) ; $i++ )
{
if (isset($data['sSearch_'.$i]) && $data['sSearch_'.$i] != "")
{
if($aColumns[$i] == 'vDeptName'){
$allDept = explode(',', $data['sSearch_'.$i]);
foreach ($allDept as $key => $value) {
if($key == 0)
$sWhere->AND->equalTo("tbl_department.vDeptName", $value);
else
$sWhere->OR->equalTo("tbl_department.vDeptName", $value);
}
}elseif($aColumns[$i] == 'vFirst')
$sWhere->AND->equalTo("tbl_user.iUserID",$data['sSearch_'.$i]);
else
$sWhere->AND->like("tbl_bids.".$aColumns[$i], "%" . $data['sSearch_'.$i] . "%");
$select->where($sWhere); // here my where clause is create
}
}
//var_dump($select->getSqlString());
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet;
}
I have others many fields to pass through where which also have same problem of paratheses
if there is no any condition i can use nest() and unnest() predicate , but it will show me that string is not nested error,
So pls help me to find the solution.
Pls attach example with solution.
here is a short example
$where = new Sql\Where();
$where->equalTo('col',thirdVal')
->NEST //start braket
->equalTo('col','someVal')
->OR
->equalTo('col','secondVal')
->UNNEST //close bracet
hope this will help

MySQL IF Condition in Where Clause

Is it possible to decide by IF Condition which Where Clause I want to choose.
Something like:
IF(DATE_FORMAT(DATE(akDate), '%a')='SAT', USE WHERECLAUSE1, USE WHERECLAUSE2)
This is the case you can still write using rather common WHERE statement such as this:
... WHERE
(
(DATE_FORMAT(DATE(akDate), '%a') = 'SAT')
AND
(WHERECLAUSE1)
)
OR
(
(DATE_FORMAT(DATE(akDate), '%a') != 'SAT')
AND
(WHERECLAUSE2)
)
where, of course, you should replace WHERECLAUSE1 and WHERECLAUSE2 with appropriate conditions.
Easy, you should read on Boolean Algebra. In your case, here we go:
A = WhereClause1
B = WhereClause2
X = Choice
You need to select lines with X && A OR lines with !X && B. So basically your expression will be: (X && A) || (!X && B). Which leads to:
(
(Choice AND WhereClause1)
OR
((NOT Choice) AND WhereClause2)
)
$query = " SELECT apt.apt_id,apt.reg_id,apt.u_id,apt.b_id,apt.apt_bathroom,apt.apt_size,apt.apt_rent,apt.apt_desc,apt.negotiable,apt.apt_status,apt.govt_program,building.b_borough,building.b_zipcode,building.b_type,building.b_intersection,building.b_intersection2,building.b_desc FROM apt LEFT JOIN building ON apt.b_id = building.b_id WHERE apt.apt_status = 1 AND ";
if ($search_size != 'empty')
{
$query .= "apt.apt_size = '".$search_size."' ";
if ($search_borough != 'empty' || $search_zipcode != 'empty' )
{
$query .= " AND ";
}
}
if ($search_borough != 'empty')
{
$query .= "building.b_borough= '".$search_borough."' ";
if ($search_zipcode != 'empty')
{
$query .= " AND ";
}
}
if ($search_zipcode != 'empty')
{
$query .= "building.b_zipcode = '".$search_zipcode."' ";
}
$query .= "ORDER BY apt.apt_id DESC LIMIT $start,$perpage ";
$query_run = mysql_query ($query);
if (!$query_run)
{
echo 'Error In the Query limit.';
}