MySQL:在ORDER之后返回X ID以下的行?

时间:2012-09-25 22:09:29

标签: mysql

我目前正在使用以下代码:

SELECT at.article_id, art.datetime, Count(at.article_id) AS common_tagged_art
FROM article_tags AS at INNER JOIN articles AS art ON at.article_id = art.article_id
WHERE at.tag_id = 4 OR at.tag_id = 3 OR at.tag_id = 1
GROUP BY at.article_id
ORDER BY common_tagged_art DESC, art.datetime DESC

这几乎返回了我需要的确切结果集,如下所示:

+-----------+---------------------+-------------+
| article_id| datetime            | common_tags |
+-----------+---------------------+-------------+
|     23    | 2012-09-25 15:37:25 |      3      |
+-----------+---------------------+-------------+
|     24    | 2012-09-25 15:37:24 |      3      |
+-----------+---------------------+-------------+
|     27    | 2012-09-25 15:37:23 |      3      |
+-----------+---------------------+-------------+
|     30    | 2012-09-25 15:37:22 |      3      |
+-----------+---------------------+-------------+
|     21    | 2012-09-25 15:37:21 |      3      |
+-----------+---------------------+-------------+

我需要调整我的查询,以便我能够发现article_id 24在我得到的结果的第二行,然后我需要它返回第二行下面的所有内容。

如果子查询中有100行,并且我发现article_id 24在第49行,我需要查询返回50-100行。我不确定这是否可以在MySQL中使用,或者在给定我的原始查询的情况下在PHP中进行更合适的任务。

到目前为止,我所看到的只是以下内容,但是在子查询之后我感到很茫然。

SELECT article_id, datetime, common_tags
FROM (
  SELECT at.article_id, art.datetime, Count(at.article_id) AS common_tags
  FROM article_tags AS at INNER JOIN articles AS art ON at.article_id = art.article_id
  WHERE at.tag_id IN (4,3,1)
  GROUP BY at.article_id
  ORDER BY common_tags DESC, art.datetime DESC
) at1
//IDENTIFY which row article_id X is on in at1
//GET any row below row X in at1

如果不是因为没有列具有静态顺序,这不会是一个问题。

任何建议都将受到赞赏。

谢谢!

2 个答案:

答案 0 :(得分:0)

我认为这不是非常有效:

SELECT at.article_id
     , art.datetime
     , COUNT(at.article_id) AS common_tagged_art
FROM article_tags AS at 
  INNER JOIN articles AS art 
    ON at.article_id = art.article_id
WHERE at.tag_id IN (4, 3, 1)
  AND at.article_id <> 23                         --- parameter: 23
GROUP BY at.article_id
HAVING (COUNT(at.article_id), art.datetime) <=
       ( SELECT COUNT(at2.article_id), art2.datetime
         FROM article_tags AS at2
           INNER JOIN articles AS art2 
             ON at2.article_id = art2.article_id
         WHERE at2.tag_id IN (4, 3, 1)
           AND at2.article_id = 23                 --- parameter: 23
       )
ORDER BY common_tagged_art DESC
       , art.datetime DESC ;

答案 1 :(得分:0)

我将在这里发布此内容,以便其他人寻找类似问题的答案。我不得不最终使用临时表,大约一半的时间表变得更快。

我创建了一个临时表,其中包含所有结果以及新的临时自动增量ID,以便我可以使用“&gt;”操作

CREATE TEMPORARY TABLE at_results (
id INTEGER(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
article_id INTEGER(10) NOT NULL,
datetime DATETIME NOT NULL,
common_tags INTEGER NOT NULL)
SELECT at.article_id, art.datetime, Count(at.article_id) AS common_tags
FROM article_tags AS at 
INNER JOIN articles AS art ON at.article_id = art.article_id
WHERE at.tag_id IN (4,3,1)
GROUP BY at.article_id
ORDER BY common_tags DESC, art.datetime DESC;

然后我创建了另一个临时表,其中只包含临时表中所需文章的id。这是在另一个表中,因为我发现MySQL不允许您多次引用临时表。这是一个已知的错误。

CREATE TEMPORARY TABLE results_article
SELECT id
FROM at_results
WHERE article_id = 23;

然后我只是提取了AI ID高于目标文章的文章。

SELECT at_results.id,article_id, datetime, common_tags
FROM at_results, at_article
WHERE at_results.id > results_article.id

这将返回我之后的确切结果。我希望这有助于其他人。不是那么精通MySQL,我花了一些时间来绊倒它。

Justs作为一个注释,我不完全确定这是否是最有效的方式。据我所知,它非常活泼。拥有更多SQL经验的人能够告诉您这是否适用于所有情况。