0

我有两个表试图加入 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_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)以及 review 表中的多个 user_id。

这是目前我的查询,我无法为我的生活工作:

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

4 回答 4

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 对 GROUP BY 的扩展

来自 MySQL 文档:

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

于 2013-04-02T21:23:18.897 回答
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;
于 2013-04-02T21:17:20.767 回答
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 和 status 过滤器必须在最里面的查询中,以避免每次都选择和连接整个 statuses 表。

于 2013-04-02T21:27:17.550 回答
0

JOIN这是我对 one和 one的尝试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

于 2013-04-02T21:42:52.987 回答