Part of JSON string before decode: ,"avail":["Wed-2","Wed-3"]
decoded : $data = json_decode($return, true);
stored in variable : $avail = $data['avail'];
//array declarations
$days = array();
$cols = array();
Format above $avail:
if($avail != ""){
foreach($avail as $k=>$v)
{
echo $v;
$array = explode('-', $v);
$day =$array[0]; // Wed
$column = $array[1]; // 2
if($column == 1)
{
$col = "morning";
}
if($column == 2)
{
$col = "afternoon";
}
if($column == 3)
{
$col = "evening";
}
echo $col ."=>". $day;
array_push($cols,$col);
array_push($days,$day);
}
}
//Now use the array($days) to match values for column 'morning' in the posts table.
echo $sql=" SELECT * , (3956 * 2 * ASIN(SQRT( POWER(SIN(('$lat' - lat) * pi()/180 / 2), 2) +COS('$lat' * pi()/180) * COS(lat * pi()/180) * POWER(SIN(('$lon' - lon) * pi()/180 / 2), 2) ))) as distance
from posts,subjects WHERE posts.afternoon IN (" . implode(", ",$days) . ") AND posts.catID = '$catid' AND posts.subname LIKE '%$subject%' AND posts.subid = subjects.subid AND posts.catID = subjects.catid AND posts.pricing <= '$rate' having distance <= '$distance' order by distance ";
echo"<br/>";
$stmt =connection::$pdo->prepare($sql);
$stmt->execute();
$place=array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$place[] = $row;
}
var_dump($place);
But it returned this error:
Fatal error: Uncaught exception 'PDOException' with message
'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'Wed' in
'where clause'' in C:\wamp\www\fetch_tutor.php on line 128 ( ! )
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column
'Wed' in 'where clause' in C:\wamp\www\fetch_tutor.php on line 128
Based on this, I understood the array ($day) supplied is taken as field name. In fact that's the value in array to check in the 'morning' field in posts table.
How do I do that please.I've wasted almost a day on this!
It should be
WHERE posts.afternoon IN ('" . implode("',' ",$days) . "')
to get something like WHERE posts.afternoon IN ('Mon','Wed','Sun').
Related
I have data that are divided quarterly in different tables. For example, first quarter for 2017, the table name is kreports_first2017 (data from jan,feb and mar).
So i have kreports_second2017, and so on until kreports_fourth2017 for year 2017. And so on for next years.
My problem is how can i select data from date range click by user. I only managed to select the table from the 'from date' and 'to date'. For example user choose to select data from 2017-04-01 to 2018-03-01. I managed to combined data from kreports_secondly2017 and kreports_first2018 only. How about the tables between them. kreports_third2017 and kreports_fourth2017? Below are my code for this:
$quar = array
(
array("first","01","02","03"),
array("second","04","05","06"),
array("third","07","08","09"),
array("fourth","10","11","12")
);
$month = substr($date1,5,2);
$year = substr($date1,0,4);
$month2 = substr($date2,5,2);
$year2 = substr($date2,0,4);
for ($row = 0; $row < 4; $row++) {
if(in_array($month,$quar[$row]))
{
$table1 = "kreports_" . $quar[$row][0] . $year . "";
}
if(in_array($month2,$quar[$row]))
{
$table2 = "kreports_" . $quar[$row][0] . $year2 . "";
}
}
$quarter = "(select * from $table1 UNION select * from $table2) AS quarter";
$sql = "SELECT DATE(r_time) AS date,SUM(login_total) AS total, SUM(login_unique) AS uniq FROM $quarter WHERE DATE(r_time) BETWEEN '$date1' AND '$date2' GROUP BY DATE(r_time) ORDER BY date ASC";
$data = $db->fetch_array($sql);
You don't need to loop for finding the quarter. Just divide the month by 3 to get the quarter. But, first, convert it to int and subtract it by 1.
$quarter1 = floor(((int)$month - 1) / 3);
$quarter2 = floor(((int)$month2 - 1) / 3);
After that, you can use these results along with the years to get the tables.
$quarter = "(";
while ($quarter1 <= $quarter2 || $year < $year2) {
$quarter .= "select * from kreports_" . $quar[$quarter1][0] . $year . " UNION ";
$quarter1 = ($quarter1 + 1) % 4;
$year += ($quarter1 == 0) ? 1 : 0; // move to next year once the quarter is set to first.
}
$quarter = substr($quarter, 0, -7); // remove the last " UNION "
$quarter .= ") AS quarter";
I'm getting issue when I try to use < symbol with AND condition in sql query.
WHERE (latitude - 0.009 < AND latitude + 0.00 >)
AND (longitude - 0.009 <
AND longitude + 0.009 > )
Here is my code in CorePHP:
<?php
ini_set("display_errors", 0);
$lat = $_REQUEST['latit'];
$long = $_REQUEST['longit'];
include ("commanvar.php");
include ("class.db.php");
$coordinates_ = '';
// function to calculate distance between two latitudes and longitudes
function distance($lat1, $lng1, $lat2, $lng2, $miles = true)
{
$pi80 = M_PI / 180;
$lat1 *= $pi80;
$lng1 *= $pi80;
$lat2 *= $pi80;
$lng2 *= $pi80;
$r = 6372.797; // mean radius of Earth in km
$dlat = $lat2 - $lat1;
$dlng = $lng2 - $lng1;
$a = sin($dlat / 2) * sin($dlat / 2) + cos($lat1) * cos($lat2) * sin($dlng / 2) * sin($dlng / 2);
$c = 2 * atan2(sqrt($a), sqrt(1 - $a));
$km = $r * $c;
return ($miles ? $km * 0.621371192 : $km);
}
$obj = new db_connect();
// added by pramod
$sql = "SELECT name,
latitude,
longitude,
TYPE
FROM (SELECT name,
TO_BINARY_FLOAT(latitude) latitude,
TO_BINARY_FLOAT(longitude) longitude,
TYPE
FROM (SELECT name,
latitude,
longitude,
TYPE,
is_number (latitude) latisnum,
is_number (longitude) longisnum
FROM (SELECT name,
REGEXP_SUBSTR (latlon,
'[^,]+',
1,
1)
latitude,
REGEXP_SUBSTR (latlon,
'[^,]+',
1,
2)
longitude,
TYPE
FROM (SELECT olt.name,
olt_details.latlon,
'olt' AS TYPE
FROM ftth.olt, ftth.olt_details
WHERE olt_id = id
UNION
SELECT name, latlon, TYPE FROM ftth.splitters
))
WHERE latitude IS NOT NULL AND longitude IS NOT NULL)
WHERE latisnum = 1 AND longisnum = 1)
WHERE (latitude - 0.009 < $lat
AND latitude + 0.00 > $lat)
AND (longitude - 0.009 < $long
AND longitude + 0.009 > $long)";
//die();
$obj->db_query($sql);
// echo $sql;
// echo $lat . ',' . $long;
// define json array coordinates and prepare it's elements for returning via AJAX
$coordinates = '{
"coordinates": [';
while ($result = $obj->db_fetch_array(1)) {
$latitude = $result['LATITUDE'];
$longitude = $result['LONGITUDE'];
$name = $result['NAME'];
$type = $result['TYPE'];
$latlon_fiber = $result['LATITUDE'] . ", " . $result['LONGITUDE'];
$distance_fromswitch = distance($lat, $long, $latitude, $longitude, FALSE);
$distance_fromswitch = floor($distance_fromswitch * 1000);
$coordinates_ .= '{ "distance":"' . $distance_fromswitch . '" ,"site_name":"' . $name . '" , "latitude":"' . $latitude . '" , "longitude":"' . $longitude . '" , "device_type":"' . $type . '" },';
}
$coordinates .= rtrim($coordinates_, ',');
$coordinates .= "]}";
echo $coordinates;
$obj->free();
?>
I'm getting the following error due to this part < AND on line WHERE (latitude - 0.009 < AND latitude + 0.00 >)
ORA-00936: missing expression
00936. 00000 - "missing expression"
I think I've used some improper syntax while using < with AND on line WHERE (latitude - 0.009 < AND latitude + 0.00 >)
What can be the correction that need to be done here?
Think of it! The error message is self-explanatory.
You're trying to compare the result of subtraction to nothing. To correct this, you have to change it to:
WHERE (latitude - 0.009 < SomeValueHere AND latitude + 0.00 > SomeValueHere)
For further details, please see: ORA-00936 missing expression
[EDIT]
As to changes made in the question...
You're asking for help in debugging (inspect) your code. Let me quote the comment to your comment:
probably the variables do not have any values and passing empty
strings into your query.. – skybunk
Thank you, #skybunk!
I'm building a job search site and I have 3 tables.
1: jobs_table: id, user_id, job_title, location, job_description, currency, salary, salary_type, employment_type, post_time, visiblity
2: applications_table: id, creator_id, applicant_id, job_id, status
3: user_table: id, profile_picture, first_name, last_name, phone_number, email_address, password, data, verification_key, modify_date
Currently, I'm selecting from the jobs_table based on user input (PHP code below), however, I'm trying to also display to the user which jobs they have already applied for and to do this I need to select from the Jobs_table (get the jobs data as I'm already doing), but also select from the applications_table with the current users ID to check if there is a row with the applicant_id and job_id if this row exists then the user has already applied for that position.
Any help is much appreciated.
PHP
$conditions = [];
// Start by processing the user input into a data structure that can be used to construct the query
if (!empty($t)) {
$conditions[] = [
['job_title', 'LIKE', '%' . $t . '%'],
];
}
if (!empty($l)) {
$conditions[] = [
['location', '=', $l],
];
}
if (!empty($s)) {
$conditions[] = [
['salary', '>=', $s],
];
}
// Loop the conditions and process them into valid SQL strings
$bindValues = [];
$whereClauseParts = [];
foreach ($conditions as $conditionSet) {
$set = [];
foreach ($conditionSet as $condition) {
list($fieldName, $operator, $value) = $condition;
$set[] = "`{$fieldName}` {$operator} :{$fieldName}";
$bindValues[$fieldName] = $value;
}
$whereClauseParts[] = implode(' OR ', $set);
}
$statement = "SELECT * FROM 001_jobs_table_as WHERE visiblity = 2";
if (!empty($whereClauseParts)) {
$statement .= " AND (" . implode(') AND (', $whereClauseParts) . ")";
}
/* Pagination Code starts */
$per_page_html = '';
$page = 1;
$start=0;
if(!empty($_GET["page"])) {
$page = $_GET["page"];
$start=($page-1) * ROW_PER_PAGE;
}
$limit=" limit " . $start . "," . ROW_PER_PAGE;
$pagination_statement = $dbh->prepare($statement);
$pagination_statement->execute($bindValues);
$row_count = $pagination_statement->rowCount();
if(!empty($row_count)){
$per_page_html .= "<div class='page_row_selector'>";
$page_count=ceil($row_count/ROW_PER_PAGE);
if($page_count>1) {
for($i=1;$i<=$page_count;$i++){
if($i==$page){
$per_page_html .= '<input type="submit" name="page" value="' . $i . '" class="btn-page active_page" />';
} else {
$per_page_html .= '<input type="submit" name="page" value="' . $i . '" class="btn-page" />';
}
}
}
$per_page_html .= "</div>";
}
$query = $statement.$limit;
$pdo_statement = $dbh->prepare($query);
$pdo_statement->execute($bindValues);
$result = $pdo_statement->fetchAll();
if(empty($result)) { ?>
<div class="job_card">
<h1 class="display-5 text-center no_result_message"> No match found. </h1>
</div>
<?php }else{
foreach($result as $row) {
$user_id = $row['user_id'];
$job_key = $row['id'];
$job_title = $row['job_title'];
$location = $row['location'];
$job_description = $row['job_description'];
$employment_type = $row['employment_type'];
$salary = $row['salary'];
$salary_type = $row['salary_type'];
$currency = $row['currency'];
$post_time = $row['post_time'];
$user_id = $row['user_id'];
$to_time = time();
$from_time = strtotime($post_time);
$time_elapsed = $to_time - $from_time;
$seconds = round(abs($time_elapsed));
$minutes = round(abs($time_elapsed) / 60);
$hours = round(abs($time_elapsed) / 3600);
$days = round(abs($time_elapsed) / 86400);
$weeks = round(abs($time_elapsed) / 604800);
// display job information in here.
} ?>
UPDATE:
I have now revised my SELECT query to the following:
$statement = "SELECT * FROM 001_jobs_table_as jt";
$statement .= " LEFT JOIN 001_application_table_as at ON at.job_id = jt.jt_id";
$statement .= " RIGHT JOIN 001_user_table_as ut ON ut.id = at.applicant_id";
$statement .= " WHERE jt.visiblity = 2";
However, I'm getting duplicates in the results, every user that applies for a job duplicates that job in the results.
What about using LEFT JOIN?
The LEFT JOIN keyword returns all records from the left table
(table1), and the matched records from the right table (table2).
SELECT *, id AS jt_id FROM jobs_table jt
LEFT JOIN applications_table at ON jt.jt_id = at.job_id AND jt.user_id = at.applicant_id
WHERE jt.visibility = 2 AND (jt.job_title LIKE :job_title) AND (jt.location = :location) AND (jt.salary >= :salary);
This should return all rows from jobs_table which match searched criteria and some of those rows can have extra data from applications_table if user already applied to that specific job (row) from jobs_table.
Something like:
jt_id user_id job_title location ... id applicant_id job_id
=================================================================
1 15 php dev london
2 23 java dev liverpool
3 44 haskell manchester
4 52 front end bristol 7 52 4
5 66 golang leeds
Row with jt_id = 4 has some extra values meaning user already applied to that job.
This should give you some directions but unfortunatelly, i didn't have a time to test this query.
EDIT
I've made a mistake. LEFT JOIN should go before WHERE clause...silly me. Check the query once again, it has been updated.
Or try it online
I'm using Zend Framework 1.12 to access a MSSQL 2008 server. I'm using FreeTDS as the database driver.
I'm using Zend_Db to generate the following query.
$obj_sel = $obj_db
-> select ()
-> from (array ('ps' => 'ProductStock'), array ('PLU', 'stock' => 'SUM(ps.stock)'))
-> join (array ('pc' => 'ProductCatalogue'), 'ps.PLU = pc.PLU', NULL)
-> join (array ('gl' => 'Gemini_Location'), 'ps.Location = gl.LocationID', array ('LocationID'))
-> where ('ps.status = 1')
-> where ('ps.PLU IS NOT NULL');
> where ('pc.rootPLU >= ?', $this -> int_start_rootplu);
-> group ('ps.PLU')
-> group ('gl.LocationID')
-> order (array ('ps.PLU', 'gl.LocationID'));
If I run and execute this, I get a query back that seems to work fine and be correct.
SELECT "ps"."PLU", SUM(ps.stock) AS "stock", "gl"."LocationID" FROM "ProductStock" AS "ps"
INNER JOIN "ProductCatalogue" AS "pc" ON ps.PLU = pc.PLU
INNER JOIN "Gemini_Location" AS "gl" ON ps.Location = gl.LocationID WHERE (ps.status = 1) AND (ps.PLU IS NOT NULL) AND (pc.rootPLU >= 93838) GROUP BY "ps"."PLU",
"gl"."LocationID" ORDER BY "ps"."PLU" ASC, "gl"."LocationID" ASC
But when I try to add a limit or an offset to the query like so:
$obj_sel = $obj_db
-> select ()
-> from (array ('ps' => 'ProductStock'), array ('PLU', 'stock' => 'SUM(ps.stock)'))
-> join (array ('pc' => 'ProductCatalogue'), 'ps.PLU = pc.PLU', NULL)
-> join (array ('gl' => 'Gemini_Location'), 'ps.Location = gl.LocationID', array ('LocationID'))
-> where ('ps.status = 1')
-> where ('ps.PLU IS NOT NULL');
> where ('pc.rootPLU >= ?', $this -> int_start_rootplu);
-> group ('ps.PLU')
-> group ('gl.LocationID')
-> order (array ('ps.PLU', 'gl.LocationID'))
-> limit (1000,2000);
I get the following query which SQL server refuses to execute.
SELECT * FROM (SELECT TOP 1000 * FROM (SELECT TOP 3000 "ps"."PLU", SUM(ps.stock) AS "stock", "gl"."LocationID" FROM "ProductStock" AS "ps"
INNER JOIN "ProductCatalogue" AS "pc" ON ps.PLU = pc.PLU
INNER JOIN "Gemini_Location" AS "gl" ON ps.Location = gl.LocationID WHERE (ps.status = 1) AND (ps.PLU IS NOT NULL) AND (pc.rootPLU >= 93838) GROUP BY "ps"."PLU",
"gl"."LocationID" ORDER BY "ps"."PLU" ASC, "gl"."LocationID" ASC) AS inner_tbl ORDER BY "ps"."PLU" , "gl"."LocationID" DESC) AS outer_tbl ORDER BY "ps"."PLU" , "gl"."LocationID" asc
I get the following error:
SQLSTATE[HY000]: General error: 4104 General SQL Server error: Check messages from the SQL Server [4104] (severity 16) [(null)]
I'm not as familiar with MSSQL as I am with MySQL or Postgres so I'm going to have to assume that the TOP technique is right. However, it's pretty clear that whatever SQL Zend DB is generating here isn't right.
Is this a known issue in Zend DB? If so, how can I work around it?
ZF 1 doesn't implement pagination on SQL Server correctly although ZF 2 does.
I've solved the problem by subclassing Zend_Db_Adapter_Pdo_Mssql:
class My_Zend_Db_Adapter_Pdo_Mssql extends Zend_Db_Adapter_Pdo_Mssql
{
/**
* #see Zend_Db_Adapter_Pdo_Mssql::limit()
*/
public function limit($sql, $count, $offset = 0)
{
$count = intval($count);
if ($count <= 0) {
/** #see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception('count parameter invalid: ' . $count);
}
$offset = intval($offset);
if ($offset < 0) {
/** #see Zend_Db_Adapter_Exception */
require_once 'Zend/Db/Adapter/Exception.php';
throw new Zend_Db_Adapter_Exception('offset parameter invalid: ' . $count);
}
if (0 == $offset) {
$sql = preg_replace('/^SELECT\s+(DISTINCT\s)?/i', 'SELECT $1TOP ' . ($count+$offset) . ' ', $sql);
return $sql;
}
$selectStart = stripos($sql, 'SELECT');
$fromStart = stripos($sql, 'FROM');
$orderby = stristr($sql, 'ORDER BY');
if ($orderby === false) {
$orderby = 'ORDER BY (SELECT 1)';
}
$sql = rtrim(str_replace($orderby, '', $sql));
$selectParams = trim(substr($sql, $selectStart + 6, $fromStart - $selectStart - 6));
$selectParams .= ', ROW_NUMBER() OVER (' . $orderby . ') AS [ZEND_ROW_NUMBER]';
$sql = substr($sql, 0, $selectStart + 6) . ' ' . $selectParams . ' ' . substr($sql, $fromStart);
$outerSql = 'SELECT * FROM (' . $sql . ') AS [ZEND_OFFSET_EMULATION]'
. ' WHERE [ZEND_OFFSET_EMULATION].[ZEND_ROW_NUMBER] BETWEEN '
. ($offset + 1) . ' AND '
. ($offset + $count)
. ' ORDER BY [ZEND_ROW_NUMBER] ASC';
return $outerSql;
}
}
I explain you the problem. I have two tables : "listing" who contain all my lists with different informations and particulary one : a city ID. I have a second table "city" who contain the complete list of all cities of my countries with many informations : latitude, longitude, city name, etc.
I want to show all listing ordered by distance between actual point (geolocalised, I have lat/lng) and cities in the listing table.
Actualy, I do this with 2 MySQL queries, and it's work :
$formula = "(6366*acos(cos(radians($latitude))*cos(radians(`latitude`))*cos(radians(`longitude`) -radians($longitude))+sin(radians($latitude))*sin(radians(`latitude`))))";
$q = "SELECT *,$formula AS dist FROM ".$this->db_city." WHERE $formula<='$distance' ORDER by dist ASC";
$q = $this->db->query($q);
$resultSQL = $q->result_array();
And this one :
if ($localization != ''){
if ($whereClause == ''){
//$whereClause .= ' WHERE address_city LIKE "'.$localization.'"';
$loc = '';
foreach ($localization as $key => $value) {
if ($loc == ''){
$loc .= '"'.$value.'"';
}else{
$loc .= ', "'.$value.'"';
}
}
$whereClause .= ' WHERE address_city IN ('.$loc.')';
}else{
//$whereClause .= ' && address_city LIKE "'.$localization.'"';
$loc = '';
foreach ($localization as $key => $value) {
if ($loc == ''){
$loc .= '"'.$value.'"';
}else{
$loc .= ', "'.$value.'"';
}
}
$whereClause .= ' && address_city IN ('.$loc.')';
}
}
$q = "SELECT * FROM ".$this->db_listing.$whereClause." ORDER BY created_stamp DESC";
It's work, but the problem is I don't have the "dist" parameter accessible in this second query, so I can't order by dist. The solution for that is to merge the first big query (the one with the formula) with the second.
I tried with LEFT JOIN, but it didn't work. Can you help me please ? Thanks !
Try this, it will going to return you all the cities those with in the radius of $distance from provided longitude and latitudes.
"SELECT *,(((acos(sin(($latitude*pi()/180)) * sin((`latitude`*pi()/180))+cos(($latitude*pi()/180)) * cos((`Latitude`*pi()/180)) * cos((($longitude-
`longitude`)*pi()/180))))*180/pi())*60*1.1515) AS distance FROM location WHERE (((acos(sin(($latitude*pi()/180)) * sin((`latitude`*pi()/180))+cos(($latitude*pi()/180)) * cos((`Latitude`*pi()/180)) * cos((($longitude-
`longitude`)*pi()/180))))*180/pi())*60*1.1515) <= $distance"
Thanks.