我有以下表结构:
table `leads`:
`id` int
`postcode` varchar
table `dealers`:
`id` int
`name` varchar
table `dealer_locs`:
`id` int
`id_dealer` int (this is what links the loc to the dealer)
`postcode` varchar
`distance` int
`lat` varchar (latitude of postcode in this row)
`long` varchar (longitude of postcode in this row)
每个经销商可以有多个dealer_locs
(位置)。我试图输出一张显示最近经销商的表格。
我有一个我写的函数(get_lat_long()),它可以获取我想要的任何邮政编码的纬度和经度。
请考虑以下代码:
$lead['postcode'] = 'M6A 3A1';
$lat_long = get_lat_long($lead['postcode']);
$lat = $lat_long['lat'];
$long = $lat_long['long'];
$sql = mysql_query("select d.id, d.name,
(6371 * 3.1415926 * SQRT(($lat - dl.lat) * ($lat - dl.lat) + COS($lat / 57.2957795) * COS(dl.lat / 57.2957795) * ($long - dl.long) * ($long - dl.long)) / 180) as distance,
dl.postcode as dl_postcode
from `dealer_locs` as dl
left join `dealers` as d on d.id = dl.id_dealer
where d.type='Real'
order by distance asc
") or die(mysql_error());
现在这段代码确实有效,但由于每个经销商都有多个位置,因此它显示重复。
以上查询和代码的示例输出:
d.name | distance
Joes Dealer | 11
Kevins Dealer | 13
Mikes Dealer | 21
Kevins Dealer | 43
Mikes Dealer | 44
Joes Dealer | 78
我想要的输出:
d.name | distance
Joes Dealer | 11
Kevins Dealer | 13
Mikes Dealer | 21
我的问题是我不知道如何写这个小组(甚至不认为这需要一个小组,或者如果这是正确的练习)。
答案 0 :(得分:0)
试试这个:
select
d.id,
d.name,
(6371 * 3.1415926 * SQRT(($lat - dl.lat) * ($lat - dl.lat) + COS($lat / 57.2957795) * COS(dl.lat / 57.2957795) * ($long - dl.long) * ($long - dl.long)) / 180) as distance,
dl.postcode as dl_postcode
from `dealer_locs` as dl
left join `dealers` as d on d.id = dl.id_dealer
where d.type='Real'
group by d.id
order by distance asc
答案 1 :(得分:0)
这应该这样做:
select
d.id, -- you can take id from here if you want
d.name,
min(6371 * 3.1415926 * SQRT(($lat - dl.lat) * ($lat - dl.lat) + COS($lat / 57.2957795) * COS(dl.lat / 57.2957795) * ($long - dl.long) * ($long - dl.long)) / 180) as distance,
dl.postcode as dl_postcode
from `dealer_locs` as dl
left join `dealers` as d on d.id = dl.id_dealer
where d.type='Real'
group by d.id
order by distance asc
答案 2 :(得分:0)
SELECT d.name,
Min(6371 * 3.1415926 * SQRT(($lat - dl.lat) * ($lat - dl.lat) + COS($lat / 57.2957795) * COS(dl.lat / 57.2957795) * ($long - dl.long) * ($long - dl.long)) / 180)) as distance,
dl.postcode as dl_postcode
FROM `dealer_locs` as dl
LEFT JOIN `dealers` as d
on d.id = dl.id_dealer
WHERE d.type='Real'
GROUP BY D.ID, D.Name
ORDER BY distance asc
您只需要使用聚合(分钟)和按名称分组。这假定名称是唯一的,否则您需要按名称和ID进行分组(假设名称可能不同)或者您可以按ID分组并让mySQL的扩展组按句柄名称进行分组。 (假设默认启用它)
此外,在这里使用LEFT Join似乎很奇怪。 where子句否定它使LEFT加入INNER。
您需要所有Dealer_Locations还是仅需要'Real'?
当你要求LEFT外连接时,由于你的where子句,你得到了
SELECT d.name,
Min(6371 * 3.1415926 * SQRT(($lat - dl.lat) * ($lat - dl.lat) + COS($lat / 57.2957795) * COS(dl.lat / 57.2957795) * ($long - dl.long) * ($long - dl.long)) / 180)) as distance,
dl.postcode as dl_postcode
FROM `dealer_locs` as dl
INNER JOIN `dealers` as d
on d.id = dl.id_dealer
WHERE d.type='Real'
GROUP BY D.ID, D.Name
ORDER BY distance asc
答案 3 :(得分:0)
如果你想为每个名字找到最近的经销商,我会将你已经拥有的东西包装到子查询中,并使用MIN()函数获得按名称分组时的最小距离,如下所示:
SELECT temp.name, MIN(temp.distance) AS distanceAway
FROM(SELECT d.id, d.name,
(6371 * 3.1415926 * SQRT(($lat - dl.lat) * ($lat - dl.lat) + COS($lat / 57.2957795) * COS(dl.lat / 57.2957795) * ($long - dl.long) * ($long - dl.long)) / 180) AS distance,
dl.postcode AS dl_postcode
FROM `dealer_locs` AS dl
LEFT JOIN `dealers` AS d ON d.id = dl.id_dealer
WHERE d.type = 'Real') temp
GROUP BY temp.name
ORDER BY distanceAway;
请注意,我将订单移至外部以订购最终结果。我也想出了“远方”#39;而不是距离,以避免歧义。您可以更改列名称以适合您的需要。