Finding drivers from nearest locations of a given location - mysql

I have 3 tables.
Table 1 - drivers
Table 2 - location
Table 3 - distance
User will search for a driver that matches a location. In drivers table the location refers to the current location of the driver. If a driver is not available in a particular location, I want a query to search for a driver that is closest to the location that the user has provide.
Table 2 is the location names and Table 3 is the distance from one place to another. But the problem is, if distance from locationid 1 to locationid 2 is stored, opposite version is not (locationid 2 to locationid 1).

This is not straight forward.
First you need to get all the location with which the given location has a relationship. This result includes the locationid and distance.
The distance with the location itself is zero. I've taken help of UNION ALL in order to make a list of <locationid,distance>.
Then make an INNER JOIN between the above list and your drivers table on matching location.
And finally sort the result set based on distance in ascending order.
SELECT
*
FROM drivers DR
INNER JOIN
(
SELECT
locationid,
0 AS distance
FROM location
WHERE locationname = 'Gulshan'
UNION ALL
SELECT
IF(L.locationid = D.fromid, D.toid, D.fromid),
D.distance
FROM location L
INNER JOIN distance D ON L.locationid IN (D.fromid,D.toid)
WHERE locationname = 'Gulshan'
) AS t
ON DR.location = t.locationid
ORDER BY t.distance
See Rextester Demo
OR
See SQL Fiddle Demo
Note: You may include LIMIT n in order to restrict the result set containing at most top n search results.
You can also include a ..WHERE distance < MAX_ALLOWABLE_DISTANCE... in your query so that the final result makes some sort of sense.

Related

Display date and and id corresponding to maximal third value in SQL

I have 3 tables in my database as you can see below: Travel, a table which contains informations about drivers, Travel, which contains informations about travels, and DroveBy, a table which displays which driver drove which Ttravel (relation between the ID's). I would like to write a query which returns the ID of a driver, its name, and the date he traveled the most. In the example below, I would like to return:
1-Armand-2012-07-18
2-Elish-2012-06-18
3-Armand-2012-07-18.
Thanks a lot
You can take the max of difference between start_time and arrived_time like below query
select d.driver_id, d.name, t.travel_date
from(
select dB.driver_id,
max(timestampdiff(minute,start_time,arrival_time)) maxTime
from droveBy dB
join travel t on dB.travel_id = t.travel_id
group by dB.driver_id)t1
join travel t on t1.maxTime = timestampdiff(minute,t.start_time,t.arrival_time)
join droveBy dB on t1.driver_id = dB.driver_id and t.travel_id = dB.travel_id
join Driver d on dB.driver_id = d.driver_id;
This gave me below result
Hope this would help you out.

SQL: Find closest number to given value with ties

I'm trying to find the closest number(s) to a given value in SQL. I have already made my query for multiple results:
SELECT *
FROM Cars
ORDER BY ABS(price - $price)
I know I can limit the table by using LIMIT 1, by which I have one number closest to the given value. But how can I include ties? Like for example when there are three or four cars with the same price? The amount of cars which have the same price is dynamic, so I can't specify a certain LIMIT.
I also know I could use SELECT TOP 1 WITH TIES, but I can't use this query because my database driver doesn't allow it. Does anybody have another idea of how to accomplish this?
Example:
car 1 = 2000
car 2 = 3000
car 3 = 3000
car 4 = 1500
When I want the cars closest to 3000, the query should return:
car 2
car 3
But without using a static LIMIT in the query, because the amount of cars with the same price can be different every time. Thanks
If your driver supports nested queries:
SELECT *
FROM CARS
WHERE ABS(price - $price) = ( SELECT MIN(ABS(price - $price)) FROM CARS )

Using multiple MySQL joins to each get multiple values

I have a table "rate" that has the columns "id", "location", "local_rate", "long_rate".
Id is the integer value to differentiate the clients. The results are grouped by location. Each location group has an entry from each client. Each client has a different local_rate and long_rate. What I need to get is the location, the lowest local_rate and the client with that rate, and the lowest long_rate and the client with that rate. There will be a row for each location in the table. If there are multiple matching results for a rate it should just pick one and return the value and the client id with that value.
Results will be displayed as:
location1 | id(min_local_rate) | min_local_rate | id(min_long_rate) | min_long_rate
location2 | id(min_local_rate) | min_local_rate | id(min_long_rate) | min_long_rate
....
Here's my query so far:
SELECT local.location, local.id, local.local_rate, long.id, long.long_rate
FROM
(SELECT MIN(local_rate), location, id FROM rate GROUP BY location) local
JOIN
(SELECT MIN(long_rate), location, id FROM rate GROUP BY location) long
ON local.location = long.location
GROUP BY local.location;
What I'm getting back is the same local client id in every row and the same long client id in every row. The location, local rates, and long rates are correct.
First, you can calculate the minimum and maximum local rates for each location in one subquery. Then, you can join back to the original data to get the client ids.
If there is only one client with the min/max, then the following should do what you want:
select l.location, l.minlr, rmin.id, l.maxlr, rmax.id
from (select location, min(local_rate) as minlr, max(local_rate) as maxlr
from rate r
group by location
) l join
rate rmin
on rmin.location = l.location and rmin.local_rate = l.minlr join
rate rmax
on rmax.location = l.location and rmax.local_rate = l.maxlr;
If there are multiple rows that match, this will produce multiple rows for each location. You question doesn't specify what to do in this case.

Variance Dissimilarity in SQL with three table

I have three table:
rtgitems
rtgusers
POI
(the tables aren't complete for reasons of space).
I want to resolve this form:
where r_i,x is the value of column "voto" for the user "rater" i for the "item" x and avg_x is the average (the division from "totalrate" and "nrrates" -> totalrate/nrrates). |G| is given and isn't a trouble.
I want this table result:
Nome (from POI) | VD_x(G)
Tour Eiffel | 23
Arc | 18
...
I tried this for the firsts two table for to take the value for calculate the average (the third table I don't know how matching with the others):
SELECT totalrate, nrrates, voto FROM rtgitems INNER JOIN rtgusers ON rtgitems.item=rtgusers.item GROUP BY rater
but don't work.
Thanks for the help.
Just focus on the rtgusers table. If you want to bring in the names, that's fine. You can do it after the variance calculation (you seem to know what a join is). The first table seems superfluous to the problem.
You can calculate the variance by pre-calculating the summary values and then applying the formula. I think this is the basic logic that you want:
SELECT ru.item, (1.0 / max(rus.n)) * sum(power(ru.voto - avg_voto), 2)
FROM rtgusers ru join
(select ru.item, avg(voto * 1.0) as avg_voto, count(*) as n
from rtgusers ru
group by ru.item
) rus
on ru.item = rus.item
group by ru.item;

MySQL multiple left join group by

There is something wrong with this MySQL code.
it seems to be returning more stock then there should be.
table positions holds the stock available (multiple positions one product)
table orderbody holds the orders ordered products (1 orderheader to many orderbody)
SELECT PRO.ProductID,
PRO.ProductCode,
SUM( POS.Qty ) AS instock,
SUM( OB.Qty ) AS onorder
FROM products AS PRO
LEFT JOIN position AS POS ON POS.ProductID = PRO.ProductID
LEFT JOIN orderbody AS OB ON OB.ProductID = PRO.ProductID
WHERE POS.ProductID = OB.ProductID
GROUP BY PRO.ProductID, POS.ProductID, OB.ProductID
i'm getting instock 320
actual stock quantity = 40
number of positions = 2 (qty 20 each)
onorder = 16 qty
actual number of orderbody = 8 rows
actually on order = 8 (each with qty = 1)
this is on one of the products
i know it has something to do with the group by but i cant work it out.
Appreciate any help received.
I had the same problem a few days ago. Try it by SELECTing from a separate query: SELECT ... FROM products, (SELECT...)..." where you have the two tables to be left joined. try to test the sub-query by itself first, and try to put it together once ot works. (once you have the data you want, and not duplicates, because that is you problem.
you are selecting this field PRO.ProductCode, but not grouping by it, at a guess it might be the problem.