无法连接两个表,一个表有多行

时间:2013-04-02 21:10:43

标签: mysql jointable

我有两个表,我试图加入MySQL:

评论:

|  review_id  |  comment       |  reviewer_id  | user_id  |
-----------------------------------------------------------
|  1          |  some text.    |  501          | 100      |    
|  2          |  lorem ipsum   |  606          | 100      |
|  3          |  blah blah.    |  798          | 120      |
|  4          |  foo bar!      |  798          | 133      |
-----------------------------------------------------------

review_status:

 |  review_id  |  status  | timestamp   |
 ----------------------------------------
 |  1          |  10      | 1364507521  |
 |  1          |  101     | 1364508057  |
 |  2          |  100     | 1364509033  |
 |  1          |  150     | 1364509149  |
 |  2          |  120     | 1364509283  |
 |  2          |  122     | 1364855948  |
 |  3          |  120     | 1364509283  |
 |  3          |  122     | 1364855948  |
 |  1          |  110     | 1364855945  |
 |  4          |  100     | 1364509283  |
 |  4          |  115     | 1364855948  |
 |  4          |  210     | 1364855945  |
 ----------------------------------------

我想要的是看起来像这样的结果:

结果

 | review_id | comment     |  reviewer_id | user_id | status | timestamp  |
 --------------------------------------------------------------------------
 | 1         | some text.  |  501         | 100     | 200    | 1364855945 | 
 | 2         | lorem ipsum |  606         | 120     | 122    | 1364855948 |
 --------------------------------------------------------------------------

我之后:1)review_status表中的最新条目2)特定范围的状态代码(在这种情况下为100 - 199)3)来自评论表的多个user_id。 / p>

这是我目前的疑问,我无法为我的生活工作:

SELECT r.review_id, r.comment, r.reviewer_id, r.user_id
FROM reviews AS r 
INNER JOIN 
   (SELECT s.status, max(s.timestamp)
    FROM review_status AS s
    WHERE s.status < 200
    AND s.status > 99;
    GROUP BY s.review_id) AS r_s
ON r.review_id = r_s.review_id
WHERE r.user_id IN (100,120);

非常感谢任何帮助!感谢。

4 个答案:

答案 0 :(得分:2)

您当前的查询存在一些问题。

  • 子查询未返回review_id,因此您无法在连接中使用该
  • 子查询中有一个额外的分号

我可能会建议重写查询以使用以下内容:

SELECT r.review_id, r.comment, r.reviewer_id, r.user_id,
  rs.status, rs.timestamp
FROM reviews AS r 
INNER JOIN review_status rs
  ON r.review_id = rs.review_id
INNER JOIN 
(
  SELECT s.review_id, max(s.timestamp) MaxDate
  FROM review_status AS s
  WHERE s.status < 200
    AND s.status > 99
  GROUP BY s.review_id
) AS r_s
  ON rs.review_id = r_s.review_id
  AND rs.timestamp = r_s.MaxDate
WHERE r.user_id IN (100,120)
  and rs.status < 200
  AND rs.status > 99

请参阅SQL Fiddle with Demo

以这种方式编写查询的主要原因是因为在您当前的查询中,您按review_id进行分组,但正在返回status。 MySQL使用GROUP BY子句的扩展,允许排除选择列表中的项目用于GROUP BY或聚合函数,但这可能会导致意外结果。 (见MySQL Extensions to GROUP BY

来自MySQL文档:

  

MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。 ...您可以通过避免不必要的列排序和分组来使用此功能来获得更好的性能。但是,当GROUP BY中未命名的每个非聚合列中的所有值对于每个组都相同时,这非常有用。服务器可以自由选择每个组中的任何值,因此除非它们相同,否则所选的值是不确定的。此外,添加ORDER BY子句不会影响每个组中值的选择。选择值后会对结果集进行排序,而ORDER BY不会影响服务器选择的值。

答案 1 :(得分:0)

试试这个:

SELECT r.*, r_s.*
FROM review_status r_s LEFT JOIN reviews r
ON r.review_id = r_s.review_id
WHERE r_s.user_id > 100 AND r_s.user_id < 120
ORDER BY r_s.timestamp DESC;

答案 2 :(得分:0)

SELECT r.review_id, r.comment, r.reviewer_id, r.user_id, tt.status,tt.timestamp
FROM (
    SELECT rs2.review_id,rs2.status,rs2.timestamp
    FROM (
        SELECT MAX(rs.timestamp) as mts
        FROM reviews rr
        JOIN review_status AS rs ON rs.review_id = rr.id
        WHERE rs.status < 200 AND rs.status > 99
        AND rr.user_id IN (100,120)
        GROUP BY rs.review_id
    ) as t
    JOIN review_status rs2 ON rs2.timestamp = t.mts
    GROUP BY rs2.review_id #remove duplicate statuses with the same timestamp
) as tt
JOIN reviews as r ON r.id = tt.review_id

user_id和状态过滤器必须位于最里面的查询中,以避免每次都选择和加入整个状态表。

答案 3 :(得分:0)

这是我尝试使用一个JOIN和一个correlated sub-query

SELECT r.*, rs.*
FROM Reviews AS r 
INNER JOIN Review_status AS rs ON r.review_id = rs.review_id 
WHERE rs.status BETWEEN 99 AND 200 AND
      r.user_id IN (100,120) AND
      rs.timestamp = (SELECT MAX(timestamp) FROM Review_status 
                      WHERE review_id = r.review_id
                      ORDER BY timestamp DESC)
ORDER BY r.review_id;

它的SQL小提琴:http://sqlfiddle.com/#!2/02f18/6