JOIN语句中双嵌套派生表中的未知列

时间:2014-06-03 07:02:55

标签: mysql sql nested-queries derived-table

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

(背后的商业逻辑:我们基本上希望获得一个用户列表,其中包括用户的最后已知位置,该位置由他们最近的Challenge 答案 - 以最新的为准。如果用户没有最后的已知位置,则不应将其列入此列表。)

我得到[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'中引用User表(别名U)。表(或任何适当的术语)。

有人可以帮忙吗?我尝试过其他方法,但都没有达到我的要求:

  1. 只有当用户在最少 1次挑战或1次回答(因此为UNION)时才会返回一行
  2. 最近(由ChallengeImage.CreatedOn和AnswerImage.CreatedOn确定)图片将用于连接
  3. 谢谢!

2 个答案:

答案 0 :(得分: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;

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

Retrieving the last record in each group

然后您将User表格与他们联系起来,这样即使用户在两个表格中都没有匹配项,您也会获得结果。

答案 1 :(得分: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;