1

在我的数据库中,有两种类型的图像:挑战和答案。它们都有 lat/lng 位置列。在此查询中,我希望选择用户最近通过 INNER JOIN 创建的挑战或答案。

(这背后的业务逻辑:我们基本上想要获得一个用户列表,其中包括用户的最后一个已知位置,该位置由他们最近的挑战答案决定 - 以最近的为准。如果用户没有最后一个已知位置,它们不应包含在此列表中。)

我得到[Err] 1054 - Unknown column 'U.Id' in 'where clause'

SELECT
    U.Id,
    U.TotalPoints,
    LastImage.Lat,
    LastImage.Lng
FROM User U
INNER JOIN
(
    SELECT Lat, Lng FROM
    (
        (SELECT Lat, Lng, CreatedOn FROM AnswerImage WHERE UserId = U.Id ORDER BY Id DESC LIMIT 1)
        UNION ALL
        (SELECT Lat, Lng, CreatedOn FROM ChallengeImage WHERE UserId = U.Id ORDER BY Id DESC LIMIT 1)
    ) LastImages ORDER BY CreatedOn DESC LIMIT 1
) LastImage
WHERE U.Type = 1 AND U.Status = 2
ORDER BY TotalPoints DESC;

我似乎无法从派生的“LastImages”表(或任何合适的术语)中引用用户表(别名 U)。

任何人都可以帮忙吗?我尝试了其他方法,但没有一个能满足我的所有要求:

  1. 仅当用户至少有1 个挑战或 1 个答案时才返回一行(因此是 UNION)
  2. 最新的(由 ChallengeImage.CreatedOn 和 AnswerImage.CreatedOn 确定)图像将用于连接

谢谢!

4

2 回答 2

2
SELECT u.id,
       u.TotalPoints,
       IF(IFNULL(a.CreatedOn, '1900-01-01') > IFNULL(c.CreatedOn, '1900-01-01'), a.Lat, c.Lat) AS Lat,
       IF(IFNULL(a.CreatedOn, '1900-01-01') > IFNULL(c.CreatedOn, '1900-01-01'), a.Lng, c.Lng) AS Lng
FROM User AS u
LEFT JOIN
    (SELECT UserId, Lat, Lng, CreatedOn
     FROM AnswerImage AS a
     JOIN (SELECT UserId, MAX(CreatedOn) AS CreatedOn
           FROM AnswerImage
           GROUP BY UserId) AS amax
     USING (UserId, CreatedOn)) AS a
    ON u.id = a.UserId
LEFT JOIN
    (SELECT UserId, Lat, Lng, CreatedOn
     FROM ChallengeImage AS c
     JOIN (SELECT UserId, MAX(CreatedOn) AS CreatedOn
           FROM ChallengeImage
           GROUP BY UserId) AS cmax
     USING (UserId, CreatedOn)) AS c
    ON u.id = c.UserId
WHERE U.Type = 1 AND U.Status = 2
    AND (a.Lat IS NOT NULL OR c.Lat IS NOT NULL)
ORDER BY TotalPoints DESC;

子查询是获取表中每组最后一行的常用方法之一,请参阅

检索每个组中的最后一条记录

然后,您将它们与User表连接起来,这样即使用户在两个表中都没有匹配项,您也会得到结果。

于 2014-06-03T07:17:12.937 回答
0

userid = u.id确实是在错误的地方。order by既然你正在拉一个记录,那么你最后一行的原因是什么?请试一试。未经测试:(

select u.id, u.totalpoints, a.lat, a.lng
from user u
join (
    select userid, lat, lng, createdon
    from AnswerImage
    union all
    select userid, lat, lng, createdon
    from ChallengeImage) a on a.userid = u.id
where u.type = 1 and u.status = 2
order by a.createdon desc
limit 1;
于 2014-06-03T07:18:05.220 回答