I am trying to adapt this select statement to my tables. This query selects all of the zip codes from a zip code table that are within a certain distance of a given zip code. However, I have a Salon table that stores the zip codes as a foreign from the zip code table. I need to select all of the salons within a certain distance of the given zip code.
DELIMITER //
CREATE PROCEDURE zip_search(lat_param FLOAT(9,6),
long_param FLOAT(9,6), dist_param INT(100)
)
BEGIN
SELECT zipcode
FROM (
SELECT z.zipcode, z.latitude, z.longitude,
p.radius,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.latitude))
* COS(RADIANS(p.longpoint - z.longitude))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.latitude)))) AS distance
FROM accounts_zip AS z
JOIN ( /* these are the query parameters */
SELECT lat_param AS latpoint, long_param AS longpoint,
dist_param AS radius, 69.0 AS distance_unit
) AS p ON 1=1
WHERE z.latitude
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.longitude
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance;
END //
I tried adding an inner join after selecting from the salon table, however I do not understand sub queries and joins very well. Any thoughts would be greatly appreciated.
DELIMITER //
CREATE PROCEDURE zip_search(lat_param FLOAT(9,6),
long_param FLOAT(9,6), dist_param INT(100)
)
BEGIN
SELECT *
FROM (
SELECT z.zipcode, z.latitude, z.longitude,
p.radius,
p.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latpoint))
* COS(RADIANS(z.latitude))
* COS(RADIANS(p.longpoint - z.longitude))
+ SIN(RADIANS(p.latpoint))
* SIN(RADIANS(z.latitude)))) AS distance
FROM accounts_salon INNER JOIN accounts_zip ON accounts_salon.id=accounts_zip.id AS z
JOIN ( /* these are the query parameters */
SELECT lat_param AS latpoint, long_param AS longpoint,
dist_param AS radius, 69.0 AS distance_unit
) AS p ON 1=1
WHERE z.latitude
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.longitude
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance;
END //
I don't think the ' AS z' in first inner join is necessary, if you try to get the join result of tables accounts_salon and accounts_zip, and treat it as the left table of second inner join, then just continure write the next inner join.
Related
Is it possible to simplify this sql query? Lots of calculations are reused and it would be nice to name each expression and use the name instead of the full expression.
SELECT SUM(T2.price * T1.amount) As price,
(SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100))) As base_price,
((SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100))) * (T3.vat / 100)) As vat_amount,
(((SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100))) * (T3.vat / 100)) + (SUM(T2.price * T1.amount) - (SUM(T2.price * T1.amount) * (T3.discount / 100)))) As total_price
I'm looking for a solution similar to this:
SELECT SUM(T2.price * T1.amount) As price,
(price - (price * (T3.discount / 100))) As base_price,
(base_price) * (T3.vat / 100)) As vat_amount,
(vat_amount) + (base_price) As total_price
I tried doing it with CTE's and subqueries as suggested but it ended up looking pretty complicated and undreadable so I decided to just do the calculations outside of sql (php in this case)
Maybe something like that:
select
(A.price - (A.price * B.p_discount)) As base_price,
((A.price - (A.price * B.p_discount)) * B.p_vat) As vat_amount,
(((A.price - (A.price * B.p_discount)) * B.p_vat) + (A.price - (A.price * B.p_discount))) As total_price
from
( select SUM(T2.price * T1.amount) As price, ...
from T1 join T2 on ....
) A
join
(select (T3.discount / 100) as p_discount , (T3.vat / 100) as p_vat ,*
from T3
) B on ...
Please I need help with adding one more condition to the below database query. I'm using Haversine Formula to get the 15 closest locations to my user's location. I have succeeded in doing this, however I wish to narrow the condition to only display the closest locations if serviceName equals a $serviceName in my query.
I wish to add WHERE serviceName="$serviceName";.
My Query:
$sql = "
SELECT uid, inCallPriceOneTime, lat, lng, distance
FROM
(
SELECT z.uid, z.inCallPriceOneTime, z.lat, z.lng,
p.radius, p.distance_unit *
DEGREES(ACOS(COS(RADIANS(p.latpoint)) *
COS(RADIANS(z.lat)) *
COS(RADIANS(p.longpoint - z.lng))
+ SIN(RADIANS(p.latpoint)) *
SIN(RADIANS(z.lat))))
AS distance
FROM selectedservice AS z
JOIN
(
SELECT $lat AS latpoint, $lng AS longpoint, 50.0 AS radius,
111.045 AS distance_unit
) AS p
WHERE z.lat
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND z.lng
BETWEEN p.longpoint - (p.radius / (p.distance_unit *
COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit *
COS(RADIANS(p.latpoint))))
) AS d
WHERE distance <= radius
ORDER BY distance LIMIT 15";
Any help will be greatly appreciated.
Thanks in advance.
I'm trying to select events in a 5 km radius and order them by likes and from oldest to newest. I know how to select events and order them by likes, but I can't figure this one out. The problem maybe is that the location is stored in a different table.
Database structure:
event plusone (like) location
id_event id_plusone id_location
location_id event_id lat
... user_id lon
... city_id
full_name
....
The SQL statement I'm trying:
SELECT 3956 * 2 * ASIN(
SQRT(POWER(SIN((50.127946 - abs(l.lat)) * pi()/180 / 2),2) + COS(50.127946 * pi()/180 ) *
COS(abs(l.lat) * pi()/180) * POWER(SIN((14.4882912 - l.lon) * pi()/180 / 2), 2) )) AS distance,e.*,COUNT( p.id_plusone ) AS
likes
FROM
event e,location l
LEFT JOIN plusone p ON p.event_id = e.id_event
WHERE
e.location_id = l.id_location AND distance<=5 GROUP BY e.id_event
ORDER BY e.timestamp DESC,likes DESC
The huge column at the beginning is calculation of distance of the event from user position using latitude and longitude.
This is what I get from the SQL debugger:
#1054 - Unknown column 'distance' in 'where clause'
Does anybody know how to do this?
Is hard to track where the error is, you should try to solve the distance part first.
SELECT
event_id,
3956 * 2 * ASIN(SQRT( POWER(SIN((50.127946 - abs(l.lat)) * pi()/180 / 2),2)
+ COS(50.127946 * pi()/180 ) * COS(abs(l.lat) * pi()/180) * POWER(SIN((14.4882912 – l.lon) * pi()/180 / 2), 2) )) AS distance,
FROM event e
JOIN location l
WHERE distance <= 5
And then join to back to the event table
SELECT e.*, count(p.id_plusone)
FROM event e
LEFT JOIN plusone p
ON p.event_id = e.id_event
JOIN ( Previous Distance Query) d
ON e.event_id = d.event_id
GROUP BY e.id_event
ORDER BY e.timestamp DESC, likes DESC
and btw, this group_by will bring you event_id plus random values for e.* so be carefull
$latitudeD= latitude;
$longitudeD = longitude;
SELECT event,
SQRT(
POW(69.1 * (coordX - $latitudeD), 2) +
POW(69.1 * ($longitudeD - coordY) * COS(coordX / 57.3), 2)) AS distance
FROM db.table WHERE SQRT(
POW(69.1 * (coordX - $latitudeD), 2) +
POW(69.1 * ($longitudeD - coordY) * COS(coordX / 57.3), 2)) < 50 ORDER BY distance
;
I'm attempting to assign the closest location to a community based on the community postcode and using the Haversine formula with SQL described here. I need to return a single scalar value but I can't seem to avoid having the second calculated distance value which is needed to determine the closest location. Help.
UPDATE Community AS c
JOIN Postcode p on p.id = c.postcode_id
JOIN (
SELECT 100.0 AS radius, 111.045 AS distance_unit
) AS a
SET c.location_id = (
SELECT l.id,
a.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latitude))
* COS(RADIANS(l.latitude))
* COS(RADIANS(p.longitude - l.longitude))
+ SIN(RADIANS(p.latitude))
* SIN(RADIANS(l.latitude)))) AS distance
FROM Location AS l
WHERE l.latitude
BETWEEN p.latitude - (a.radius / a.distance_unit)
AND p.latitude + (a.radius / a.distance_unit)
AND l.longitude
BETWEEN p.longitude - (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
AND p.longitude + (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
HAVING distance <= a.radius
ORDER BY distance
LIMIT 1
)
Using the structure you have, you need to move the distance calculation into the WHERE and ORDER BY clauses:
SET c.location_id = (
SELECT l.id
FROM Location AS l
WHERE l.latitude
BETWEEN p.latitude - (a.radius / a.distance_unit)
AND p.latitude + (a.radius / a.distance_unit)
AND l.longitude
BETWEEN p.longitude - (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
AND p.longitude + (a.radius / (a.distance_unit * COS(RADIANS(p.latitude))))
AND a.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latitude))
* COS(RADIANS(l.latitude))
* COS(RADIANS(p.longitude - l.longitude))
+ SIN(RADIANS(p.latitude))
* SIN(RADIANS(l.latitude)))) <= a.radius
ORDER BY a.distance_unit
* DEGREES(ACOS(COS(RADIANS(p.latitude))
* COS(RADIANS(l.latitude))
* COS(RADIANS(p.longitude - l.longitude))
+ SIN(RADIANS(p.latitude))
* SIN(RADIANS(l.latitude))))
LIMIT 1
)
I am trying to count of coupons sold by each store from the list of stores within 20 miles range. I know the following syntax will work if there is only 1 store.
SELECT sum(couponscount) as count where restaurant IN (SELECT storename where bhal bhal bhal and output is one value)
What is I the IN (SELECTstorenamewhere bhal bhal bhal and output is multiple values) will return multiple values?
Like in my case the complete SQL is like and its not working
SELECT sum(couponscount) as count FROM `coupons` having `restaurant` IN (SELECT `storename`, ((ACOS(SIN(-27.561264299999998 * PI()/180) * SIN(latitude * PI()/180) + COS(-27.561264299999998 * PI()/180) * COS(latitude * PI()/180) * COS((153.07304890000003 – longitude) * PI()/180)) *180 / PI( )) *60 * 1.1515) AS `distance` FROM `stores` WHERE `status`=’active’ HAVING `distance` <=20)
Is there anyway to make it working?
SELECT sum(couponscount) AS COUNT,restaurant
FROM `coupons`
WHERE `restaurant` IN
(SELECT `storename`
FROM `stores`
WHERE `status`='active'
AND
((ACOS(SIN(-27.561264299999998 * PI()/180) * SIN(latitude * PI()/180) + COS(-27.561264299999998 * PI()/180) * COS(latitude * PI()/180) * COS((153.07304890000003 – longitude) * PI()/180)) *180 / PI()) *60 * 1.1515) <=20)
GROUP BY restaurant
Also use proper quotes for active.
Presumably, you want to get the count of coupons from stores within a distance of 20. Moving the having condition to a where clause should do what you want:
SELECT sum(couponscount) as count
FROM `coupons`
WHERE `restaurant` IN (SELECT `storename`
FROM `stores`
WHERE `status` = 'active' AND
((ACOS(SIN(-27.561264299999998 * PI()/180) * SIN(latitude * PI()/180) + COS(-27.561264299999998 * PI()/180) * COS(latitude * PI()/180) * COS((153.07304890000003 – longitude) * PI()/180)) *180 / PI( )) *60 * 1.1515) <= 20
);
You had a major syntax problem because your subquery returned two columns. When you use a subquery with in, you can only return one column, in this case, storename. I moved the code for the distance calculation to the where clause. No having clause is needed either in the subquery or the outer query.