Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php MYSQL连接和组/不同_Php_Mysql_Database_Join - Fatal编程技术网

Php MYSQL连接和组/不同

Php MYSQL连接和组/不同,php,mysql,database,join,Php,Mysql,Database,Join,我将3个表连接在一起,以获得特定区域中的用户。表的缩小示例: USER Table (stores all user information) ID | Name ---------- 1 John 2 Joe 3 Mike GEO (has all geo location info; including latitude and longitude; which im excluding for the example ) ID | CITY -----------

我将3个表连接在一起,以获得特定区域中的用户。表的缩小示例:

USER Table (stores all user information) 
ID | Name
----------
 1   John
 2   Joe
 3   Mike 

GEO (has all geo location info; including latitude and longitude; which im excluding for the example )
ID | CITY 
-------------
 1 | ORLANDO
 2 | MIAMI
 3 | DAYTONA

LOCATIONS (stores each users location; each user has multiple locations)
ID | AREA (id = user.id, geo = geo.id)
--------
 1 | 1
 1 | 2
 1 | 3
 2 | 1
 3 | 1
 3 | 3
我在php中创建了一个函数,用于以特定半径(不包括整个函数,因为它不相关)提取给定LAT/LONG的结果:

但这不起作用,因为我必须选择trig语句作为距离,所以我不能只从GEO表中选择id

我在试图获得独特的用户方面束手无策;但仍在所有用户位置进行搜索。我知道我可以在php中循环结果并重建它们;然而,这个查询很容易返回数千个结果,因为每个用户的位置都显示在结果中,为了提高速度,我不希望这样做

如果能在正确的方向上提供帮助,我们将不胜感激

添加

稍微详细说明一下结果问题,如果您在ORLANDO上运行此查询,半径将扩展到DAYTONA,如果用户在DAYTONA,您将得到

USER | CITY
-----------
 1  | ORLAND
 1  | DAYTONA
 2  | ORLANDO
 3  | ORLANDO
 3  | DAYTONA
这将导致用户1和用户3的重复

但是当您按user.id分组时,您只会得到

 USER | CITY
-----------
 2  | ORLANDO

这会删除用户1和3,因为当其分组时,它只显示其区域为DAYTONA

如果您使用
WHERE
而不是
have
,您将能够使用
GROUP BY
/
DISTINCT
并捕获所有类似的信息:

SELECT u.id AS USERID
    FROM `GEO` g
    JOIN `LOCATIONS` l ON l.`AREA` = g.`ID`
    JOIN `USER` u ON l.`ID` = u.`ID`
    WHERE (6371 * ACOS(COS(RADIANS({$lat})) * COS(RADIANS(g.latitude)) * COS(RADIANS(g.longitude) - RADIANS({$long})) + SIN(RADIANS({$lat})) * SIN(RADIANS(g.latitude)))) <= {$radius}
    GROUP BY u.`ID`
  • 请注意,如果您还想选择距离,您仍然可以像以前一样在“选择字段”列表中输入;但是,如果使用
    DISTINCT
    只会得到一个,而如果使用
    groupby
    则可以连接所有距离
  • 我建议同时尝试
    分组
    不同的
    ,因为性能差异可能非常极端且不可预测。(参见示例)
  • 我只是想知道,但是预先计算诸如
    ACOS(COS(RADIANS({$lat}))
    之类的部分会更有效,而不是在运行中进行计算,有什么理由保持这样吗
  • 此外,您可能希望以弧度为单位存储long/lat值,以便进一步优化

我的朋友,你真是太棒了。MAX一直在非法使用group by;因此我删除了MAX,并进行了一次select DISTINCT(u.id)它似乎在工作!至于预计算,你是建议先在我的php函数中进行预计算,然后再传递吗?你认为这会显示搜索时间的减少吗?TBH这部分是我在另一篇文章中发现的,因为按半径搜索超出了我的理解范围。位置表来自美国zipcode数据库,它具有简单的lat/long。我可以用弧度来重建它,这样就不必在查询中进行;每一秒都会有帮助。确切地说,一个简单的“重建”使数据库中的lon和lat存储在弧度中,这会使它增加一点,并使查询更简单。另外,带有变量的部分,如
ACOS(COS(radians({$lat}))
在yuur查询期间是一个常量,因此您只能使用php对其进行预计算并使用其结果,例如,
$pc_lat=acos(cos(deg2rad($lat)))
。关于MAX,你说得很对,这是我的疏忽,但是,我所能看到的是:你不需要它,因为单个值的最大值总是那个值。在注意到你的修订之前,我将根据上面的命令进行更新。与我上面的评论一样,我仍然得到MAX错误;但是删除MAX和GROUP BY并替换with DISTINCT(u.id)有效…只是出于好奇,你知道为什么MAX会给无效的group by吗?哈哈,我还在编辑,现在它已经更新了。MAX函数本身就是一个聚合函数,它们不允许在select字段之外。请参阅
 USER | CITY
-----------
 2  | ORLANDO
SELECT u.id AS USERID
    FROM `GEO` g
    JOIN `LOCATIONS` l ON l.`AREA` = g.`ID`
    JOIN `USER` u ON l.`ID` = u.`ID`
    WHERE (6371 * ACOS(COS(RADIANS({$lat})) * COS(RADIANS(g.latitude)) * COS(RADIANS(g.longitude) - RADIANS({$long})) + SIN(RADIANS({$lat})) * SIN(RADIANS(g.latitude)))) <= {$radius}
    GROUP BY u.`ID`
SELECT u.id AS USERID
    FROM `GEO` g
    JOIN `LOCATIONS` l ON 
        (6371 * ACOS(COS(RADIANS({$lat})) * COS(RADIANS(g.latitude)) * COS(RADIANS(g.longitude) - RADIANS({$long})) + SIN(RADIANS({$lat})) * SIN(RADIANS(g.latitude)))) <= {$radius}
        AND l.`AREA` = g.`ID`
    JOIN `USER` u ON l.`ID` = u.`ID`        
    GROUP BY u.`ID`