Subquery calculation error? - php

Why is this query not working?
$query = ("SELECT * FROM
(SELECT *, (
(((endingLatitude - " . $h . ")(endingLatitude - " . $h . "))
/" . pow($r1, 2) . ")
+
((endingLongitude - " . $k . ")(endingLongitude - " . $k . "))
/" . pow($r2, 2) . "
) AS point2
FROM (SELECT *, ((
(
((startingLatitude - " . $h . ")(startingLatitude - " . $h . "))
/" . pow($r1, 2) . ")
+
((startingLongitude - " . $k . ")(startingLongitude - " . $k . "))
/" . pow($r2, 2) . "))
AS point1
FROM (SELECT * FROM trips WHERE distance >='" . ($distance * .25) . "') as query1)
as query2) as query3 WHERE point1 <= 1 AND point2 <= 1 LIMIT 0 , 10;");
$result = mysqli_query($con, $query);
$h and $k is the ellipses x and y coordinates respectively. I am using a formula found here to calculate whether or not the two points, (startingLat,startingLong) and (endingLat,endingLong) are within an ellipse with vertical height $r1 and horizontal height $r2. I am also limiting the rows that I search to rows that have a distance cell value of greater than $distance * .25.
I think it might have something to do with a parenthesis error or something to do with the way I am sub querying/performing my calculations.
Using
die(mysqli_error($con));
returns an error of You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(endingLatitude - 36.9564753)) /796.842964388) + ((endingLongitud' at line 3

I believe you have to use Mysql multiplication arithmetic operator, *.
https://dev.mysql.com/doc/refman/5.0/en/arithmetic-functions.html#operator_times
Instead of:
(endingLatitude - " . $h . ")(endingLatitude - " . $h . ")
Do this...
(endingLatitude - " . $h . ") * (endingLatitude - " . $h . ")

Related

Error GroupBy PHP + MSSQL

$Read->FullRead("SELECT an_promo_page_tipo_blocos.title,"
. "an_promo_page_tipo_blocos.img,"
. "an_promo_bloco_anexo.status,"
. "an_promo_bloco_anexo.pg_id,"
. "an_promo_bloco_anexo.id,"
. "an_promo_bloco_anexo.promo_id,"
. "an_promo_bloco_anexo.tipo_bloco,"
. "an_promo_bloco_anexo.bloco_id "
. "FROM an_promo_bloco_anexo "
. "INNER JOIN an_promo_page "
. "ON "
. "an_promo_bloco_anexo.pg_id = an_promo_page.pg_id"
. " INNER JOIN an_promo_page_tipo_blocos ON an_promo_bloco_anexo.tipo_bloco = an_promo_page_tipo_blocos.id "
. "WHERE an_promo_bloco_anexo.promo_id = :pro AND an_promo_bloco_anexo.pg_id = :pi"
. " AND an_promo_bloco_anexo.pg_tipo = :pt ORDER BY an_promo_bloco_anexo.ordem, an_promo_page_tipo_blocos.title"
. " AND GROUP BY "
. "an_promo_page_tipo_blocos,"
. "an_promo_bloco_anexo"
. "", "pro={$PromoId}&pi={$p['pg_id']}&pt={$p['pg_tipo']}");
Result:
protected 'message' => string 'SQLSTATE[42000]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]Column 'an_promobar.promo_title' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.' (length=217)
Anyone can help me?
When you use GROUP BY you need to group by all the fields that you are not using an aggregate function against (ie: SUM, MAX, etc).
GROUP BY is also not part of a WHERE clause; it stands alone.
Given your query has no aggregate functions, I don't see why you're using GROUP BY at all.
Try this.
$Read->FullRead("SELECT an_promo_page_tipo_blocos.title,"
. "an_promo_page_tipo_blocos.img,"
. "an_promo_bloco_anexo.status,"
. "an_promo_bloco_anexo.pg_id,"
. "an_promo_bloco_anexo.id,"
. "an_promo_bloco_anexo.promo_id,"
. "an_promo_bloco_anexo.tipo_bloco,"
. "an_promo_bloco_anexo.bloco_id "
. "FROM an_promo_bloco_anexo "
. "INNER JOIN an_promo_page "
. "ON "
. "an_promo_bloco_anexo.pg_id = an_promo_page.pg_id"
. " INNER JOIN an_promo_page_tipo_blocos ON an_promo_bloco_anexo.tipo_bloco = an_promo_page_tipo_blocos.id "
. "WHERE an_promo_bloco_anexo.promo_id = :pro AND an_promo_bloco_anexo.pg_id = :pi"
. " AND an_promo_bloco_anexo.pg_tipo = :pt ORDER BY an_promo_bloco_anexo.ordem, an_promo_page_tipo_blocos.title"
. "", "pro={$PromoId}&pi={$p['pg_id']}&pt={$p['pg_tipo']}");

Codeigniter 3 query builder auto quote wrongly

I'm am trying to get the sql format below
SELECT * FROM `ci_nest` WHERE `lft` > 9 AND `rgt` < 28 AND `rgt` = `lft` + 1 ORDER BY `lft`
However Codeigniter 3 is inserting the quotes at the wrong place.
My Code as follows
$this->db->where($leftcol . ' > ' . $leftval . ' AND ' . $rightcol . ' < ' . $rightval);
$this->db->where($rightcol . " = " . $leftcol . " +1");
$this->db->order_by($leftcol);
$query = $this->db->get($this->table_name);
What codeigniter query output is
SELECT *
FROM `ci_nest`
WHERE `lft` > 9 AND `rgt` < 28
AND `rgt` = `lft` `+1`
ORDER BY `lft`
As you can see at the line and rgt = lft + 1 is being formatted wrongly by codeigniter 3 query builder.
Any workaround for this issue would be appreciated.
Disable the backticks by the optional 3rd parameter and create them by your own.
$this->db->where($rightcol, '`'.$leftcol.'`+1', FALSE);
Or with double quotes, seems better.
$this->db->where($rightcol, "`$leftcol`+1", FALSE);
For now a quick fix I found is to use Codeigniter 3 query method instead of the query builder.
$query = $this->db->query("SELECT * FROM `{$this->table_name}` WHERE
`{$leftcol}` > {$leftval} AND `{$rightcol}` < {$rightval} AND
`{$rightcol}` = `{$leftcol}` + 1 ORDER BY `{$leftcol}`");
Try this :
$this->db->where($leftcol . ' > ' . $leftval . ' AND ' . $rightcol . ' < ' . $rightval);
$this->db->where($rightcol . " = " . $leftcol + 1);
$this->db->order_by($leftcol);
$query = $this->db->get($this->table_name);

PHP/Mysql: optimize query

I have the following script that retrieve numbers from 2 tables, make a sum, and the value is updated into a 3th table.
$query = "SELECT (SELECT SUM(net_amount) FROM fin_costos WHERE month='1' AND group_of_costos='general' AND year_analysis='2014' ) +
(SELECT SUM(net_amount) FROM em2_fin_costs WHERE month='1' AND group_of_costos='general' AND year_analysis='2014') AS total";
$result = mysqli_query($mysqli,$query);
while($row = mysqli_fetch_array($result)){$valor_final = $row['total']; }
$query_update="UPDATE fusion_analysis SET jan='$valor_final' WHERE year_for_analysis='2014' AND item_for_analysis='general' AND category='general'";
$result = mysqli_query($mysqli,$query_update);
I need to run the same script for each month of the year. Everything is exaclty the same except the variable 'month' that changes from 1 to 12 and the SET in UPDATE where the value is uploaded for each month ('jan','feb', 'mar'...etc)
I'm currently just copying and pasting the same script changing this few parameters but I believe there is a smarter way to do this in less lines of code I have
See date function of PHP:
$query = "SELECT (SELECT SUM(net_amount)"
. " FROM fin_costos"
. " WHERE month='".date('n')."'"
." AND group_of_costos='general' AND year_analysis='".date("Y")."' ) +"
."(SELECT SUM(net_amount) FROM em2_fin_costs WHERE month='".date('n')."'"
. " AND group_of_costos='general' AND year_analysis='".date("Y")."') AS total";
$query_update="UPDATE fusion_analysis"
. " SET `". strtolower(date('M'))."`='$valor_final'"
. " WHERE year_for_analysis='".date("Y")."'"
. " AND item_for_analysis='general'"
. " AND category='general'";
NOTE:
Y - A full numeric representation of a year, 4 digits like 2014
n - Numeric representation of a month, without leading zeros 1 - 12
M - A short textual representation of a month, three letters Jan through Dec
For month as short textual I've used the strtolower function to make it lowercase.
UPDATE
Based on OP comment:
for ($i = 1; $i <= 12; $i++) {
$query = "SELECT (SELECT SUM(net_amount)"
. " FROM fin_costos"
. " WHERE month='" . $i . "'"
. " AND group_of_costos='general' AND year_analysis='" . date("Y") . "' ) +"
. "(SELECT SUM(net_amount) FROM em2_fin_costs WHERE month='" . $i . "'"
. " AND group_of_costos='general' AND year_analysis='" . date("Y") . "') AS total";
$result = mysqli_query($mysqli, $query);
$row = mysqli_fetch_assoc($result);
$valor_final = $row['total'];
$monthName = strtolower(date('M', strtotime(date("Y") . "-" . str_pad($month,2, "0", STR_PAD_LEFT) . "-" . date("01") )));
$query_update = "UPDATE fusion_analysis"
. " SET `" . $monthName . "`=' " . $valor_final . "'"
. " WHERE year_for_analysis='" . date("Y") . "'"
. " AND item_for_analysis='general'"
. " AND category='general'";
mysqli_query($mysqli, $query_update);
}

Mysql Result Return Problem

I'm creating a project in FuelPHP, with php + mysql.
I have this database query (I'm not using their built in query builder because its just a pain in the ass for complex queries).
$sql = DB::query('
SELECT game_id, lati, longi,
acos(sin (' . $lat . ')
* sin (radians( lati ))
+ cos (' . $lat . ')
* cos (radians(lati))
* cos (radians(longi) - ' . $lon . '))
*' . $R . ' AS D
FROM (
SELECT game_id, lati, longi
FROM games
WHERE lati > ' . $minLat .
' AND lati <' . $maxLat .
' AND longi > ' . $minLon .
' AND longi < ' . $maxLon .
') AS firstcut
WHERE
acos(sin (' . $lat . ')
* sin (radians( lati ))
+ cos (' . $lat . ')
* cos (radians(lati))
* cos (radians(longi) - ' . $lon . '))
*' . $R . '<' . $rad .
' ORDER BY D');
If I execute this and print_r(result) the number of rows is displayed i.e 2.
However I cant treat, or convert this result into an array, so I cant
foreach($result as $row) { echo $row['id'] . ' + ' . $row['D']}
Or something similar.
If I paste this code and replace the php variables with real values into phpmyadmin, I get the green 'The query was executed successfully' message but no rows are returned (two rows should be returned, there is not even a 'This query returned zero rows' message).
I dont have much experience with this kind of nested/complex sql queries, so any help would be appreciated.
Thanks.
You need to pass DB::SELECT as the second param for DB::query().
You might want to use the as_array method from the database result. Or take a look here: http://fuelphp.com/docs/classes/database/usage.html#results

Zend_db & Zend_paginator - Not having a fun time

I am having a serious problem converting my 'select' statement into something that will work with the zend paginator... could someone have a crack at it, as I am having no luck...
Here is my query:
$query = "SELECT
user_id, name, gender, city, province, country, image_id, one_liner, self_description, reputation
FROM
users
WHERE
(
(69.1 * (latitude - " . $user->latitude . ")) *
(69.1 * (latitude - " . $user->latitude . "))
) + (
(69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3)) *
(69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3))
) < " . pow($radius, 2) . "
ORDER BY
(
(69.1 * (latitude - " . $user->latitude . ")) *
(69.1 * (latitude - " . $user->latitude . "))
) + (
(69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3)) *
(69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3))
Here is what I have so far:
$select = $db->select();
$select->from(
array('users'),
array(
'user_id',
'name',
'gender',
'city',
'province',
'country',
'image_id',
'one_liner',
'self_description',
'reputation'
)
);
$select->where("(69.1 * (latitude - " . $user->latitude . ")) * (69.1 * (latitude - " . $user->latitude . "))) + ((69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3)) * (69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3))) < " . pow($radius, 2));
$select->order("(69.1 * (latitude - " . $user->latitude . ")) * (69.1 * (latitude - " . $user->latitude . "))) + ((69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3)) * (69.1 * (longitude - " . $user->longitude . ") * COS(" . $user->latitude . " / 57.3))) ASC");
Why do you have "<" in your order by clause?
What does this have to do with Zend_Paginator? Ah, do you have the query and you don't know how to make a paginator with it, or is the paginator not working with this query?
The only thing I can see is you're missing an opening parenthesis in both the where() and order() clause:
$select->where("((69.1 * [...] ");
$select->order("((69.1 * [...] ");
^
So maybe Zend_Paginator isn't working because the SQL query has errors?
And of course I have to ask: are those variables you're interpolating safe, or should you really be using $db->quote($user->latitude, Zend_Db::FLOAT_TYPE)?
Assuming you are using MVC-pattern, won't this work?
in your bootstrap:
Zend_View_Helper_PaginationControl::setDefaultViewPartial('pagination.phtml');
in your controller:
$page = Zend_Paginator::factory($select);
$page->setCurrentPageNumber($this->_getParam('page', 1));
$page->setItemCountPerPage($this->_getParam('par', 20));
$this->view->results= $page;
in your view:
<?php foreach($this->results as $result) : ?>
<!-- print some $result stuff here -->
<?php endforeach;?>
<?= $this->results ?>
then place a pagination.phtml example that you can find on zend manual
-Lo

Categories