Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.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
多对多关系的3个表之间的SQL查询_Sql_Date_Many To Many_Max - Fatal编程技术网

多对多关系的3个表之间的SQL查询

多对多关系的3个表之间的SQL查询,sql,date,many-to-many,max,Sql,Date,Many To Many,Max,我有三个表:朋友,位置,朋友位置 friend\u location是一个联接表,用于允许friends和位置之间的多对多关系,因此这些表将如下所示: SELECT f.id, f.name, last_known_date, l.Lat, L.Lon from Friends f join ( select f.id, MAX(l.Date) as last_known_date from Friends f JOIN Friend_Location f

我有三个表:
朋友
位置
朋友位置

friend\u location
是一个联接表,用于允许
friends
位置之间的多对多关系,因此这些表将如下所示:

SELECT  f.id, f.name, last_known_date, l.Lat, L.Lon
from Friends f
join
(
    select  f.id, MAX(l.Date) as last_known_date
    from    Friends f
    JOIN    Friend_Location fl on f.ID = fl.Friend_ID
    JOIN    Location l on l.ID = fl.Location_ID
    GROUP BY f.id
) FLMax
on FLMax.id = f.id
join Friend_Location fl on fl.friend_ID = f.ID
join Location l on fl.location_ID = l.ID AND l.Date = FLMax.Last_Known_Date
朋友


ID  | Name
1   | Jerry
2   | Nelson
3   | Paul

ID  | Friend | Last Know Location  | last know date
1   | Jerry  |  45.3 , 49.3        | 2011-04-03
2   | Nelson |  34.3 , 67.3        | 2012-03-01
3   | Paul   |  32.2 , 107.2       | 2012-05-03
位置


ID  | Date       | Lat   | Lon 
1   | 2012-03-01 | 34.3  |  67.3
2   | 2011-04-03 | 45.3  |  49.3
3   | 2012-05-03 | 32.2  |  107.2

Friend_ID  | Location_id
1          |  2
2          |  1
3          |  3
2          |  2
朋友位置


ID  | Date       | Lat   | Lon 
1   | 2012-03-01 | 34.3  |  67.3
2   | 2011-04-03 | 45.3  |  49.3
3   | 2012-05-03 | 32.2  |  107.2

Friend_ID  | Location_id
1          |  2
2          |  1
3          |  3
2          |  2
我想做的是获取每个朋友的最新位置

结果


ID  | Name
1   | Jerry
2   | Nelson
3   | Paul

ID  | Friend | Last Know Location  | last know date
1   | Jerry  |  45.3 , 49.3        | 2011-04-03
2   | Nelson |  34.3 , 67.3        | 2012-03-01
3   | Paul   |  32.2 , 107.2       | 2012-05-03
这是我在查看各种示例后尝试的,但它返回到许多结果,并且不正确:


    select f.id , f.name , last_known_date
    from friends f, (

    select distinct fl.friend_id as friend_id, fl.location_id as location_id, m.date as last_known_date
    from friend_location fl

    inner join (
        select location.id as id, max(date) as date
        from location
        group by location.id
    ) m

    on fl.location_id=m.id

    ) as y
    where f.id=y.friend_id

如有任何建议,将不胜感激

您的数据布局有点奇怪,因为日期在位置表中。因此,下面检索每个朋友的最新日期:

select fl.friend_id, max(l.date) as maxdate
from friend_location fl
     location l join
     on fl.location_id = l.location_id
现在,让我们回到这个查询的信息中:

select f.*, maxdate, l.*
from (select fl.friend_id, max(l.date) as maxdate
      from friend_location fl
      JOIN location l
           on fl.location_id = l.id
      group by fl.friend_id
     ) flmax join
     friends f
       on flmax.friend_id = f.id
     join location l
       on l.date = flmax.maxdate

假设这些地点没有重复的日期,这将起作用。如果是这样的话,查询就要复杂一点。我们能做出这样的假设吗?

你可以这样做:

SELECT  f.id, f.name, last_known_date, l.Lat, L.Lon
from Friends f
join
(
    select  f.id, MAX(l.Date) as last_known_date
    from    Friends f
    JOIN    Friend_Location fl on f.ID = fl.Friend_ID
    JOIN    Location l on l.ID = fl.Location_ID
    GROUP BY f.id
) FLMax
on FLMax.id = f.id
join Friend_Location fl on fl.friend_ID = f.ID
join Location l on fl.location_ID = l.ID AND l.Date = FLMax.Last_Known_Date
基本上,您的问题是您正在按location.id进行分组,这将为您提供所有位置,因为id是唯一的

这仅适用于朋友在任何时间只能在一个位置的情况。

您可以使用:

SELECT 
    a.*,
    CONCAT(d.Lat, ' , ', d.Lon) AS last_known_location,
    d.Date AS last_known_date
FROM 
    friends a
JOIN
(
    SELECT   a.Friend_ID, MAX(b.Date) AS maxdate
    FROM     friend_location a
    JOIN     location b ON a.Location_id = b.ID
    GROUP BY a.Friend_ID
) b ON a.ID = b.Friend_ID
JOIN
    friend_location c ON b.Friend_ID = c.Friend_ID
JOIN
    location d ON c.Location_id = d.ID AND b.maxdate = d.Date

Gregs查询在我看来是正确的,我提出了类似的查询(见下文)。然而,当前的db模式不能处理两个朋友以不同顺序访问相同位置的情况。对我来说,日期列应该在friend_location表中,而不是location表中。但是,如果不是,则查询为:

SELECT F.ID, F.Name AS Friend, L.Lat, L.Lon, L.Date
FROM
(
    SELECT MAX(L.date) AS max_date, F.ID
    FROM Friends F 
    JOIN friend_location FL ON F.ID=FL.Friend_ID
    JOIN Location L ON L.ID=FL.Location_id
    GROUP BY F.ID
) AS X
JOIN Friends F ON X.ID=F.ID
JOIN friend_location FL ON F.ID=FL.Friend_ID
JOIN location L ON L.ID=FL.Location_id AND L.Date=X.max_date

通过将日期放在Friend_Location表中,可以更好地规范化该表。使用您当前的设计,朋友多次登录同一位置将创建多个位置记录。非常感谢大家!他们都做得很好。我唯一添加的是一个独特的,以确保我只得到一个结果为每个条目回来。请列出您正在使用的数据库类型。。。这很大程度上影响了答案,因为窗口函数使事物更加流线型和简洁(但在所有数据库中都不可用)。您可能需要考虑将最后一个已知日期移到单独的表中。