1

我有这个 mysql 语句,但在子查询错误中收到 LIMIT

SELECT  id
FROM    articles
WHERE  section=1 AND id NOT IN 
        (
        SELECT  id
        FROM    articles
        WHERE   is_top_story=1  ORDER BY timestamp DESC LIMIT 2
        )

我想从表中选择所有 id-s,其中 section=1 和 id-s 不在我的内部(第二个)语句中

+--id--+section+-is_top_story-+--timestamp--+
|  54  |   1   |     1        |    130      |
|  70  |   2   |     0        |    129      |      
|  98  |   3   |     1        |    128      |
|  14  |   1   |     1        |    127      |
|  58  |   4   |     0        |    126      |
|  13  |   3   |     1        |    125      |
|  64  |   1   |     1        |    124      |
|  33  |   1   |     1        |    123      |

我的 sql 应该返回 64 和 33(它们是 section=1 和 is_top_story=1),因为 54 和 14(在内部语句中)

如果有人可以给我一些代码,我将不胜感激

谢谢

4

2 回答 2

6

这个怎么样:

SELECT a.id, a.times
  FROM articles AS a
  LEFT JOIN (
       SELECT id
         FROM articles
        WHERE is_top_story =1
     ORDER BY times DESC LIMIT 2) AS ax
  USING (id)
WHERE section = 1 AND ax.id IS NULL;

当您需要限制子查询时,加入是一种常见的解决方法;需要排除逻辑只需将这些“左连接-joined.id IS NULL”部分添加到查询中。)

更新:你的例子有点困惑。您引用的原始查询是“取一些 section = 1 的文章,然后取出那些属于 2 个最近的 top_stories 的文章”。但是在您的示例中,在选择这些要忽略的故事时,还应考虑该部分...

使用该条件更新我的查询实际上也很容易:只需替换

WHERE is_top_story = 1

WHERE is_top_story = 1 AND section = 1

...但我认为在客户端代码中可能会更好地解决它。首先,您发送一个简单的查询,没有任何连接:

    SELECT id, is_top_story 
      FROM articles 
     WHERE section = 1
  ORDER BY times DESC;

然后,您只需遍历获取的行集,并忽略两个带有“is_top_story”标志的第一个元素,如下所示:

  ...
  $topStoriesToIgnore = 2;
  foreach ($rowset as $row) {
    if ($row->is_top_story && $topStoriesToIgnore-- > 0) {
      continue;  
    }
    // actual processing code goes here
  }
于 2012-05-07T13:54:33.687 回答
0

我不知道这是不是你想要的,这个问题有点混乱。我不明白你为什么对同一个表使用子查询。无论如何 LIMIT 与 MSSQL 的“TOP”相同,因此 LIMIT 2 应该只返回两条记录。

如果这不是您想要的,请发表评论,我将编辑我的答案:

SELECT  id
FROM    articles
WHERE  section=1 AND is_top_story != 1
ORDER BY timestamp DESC 
于 2012-05-07T14:02:09.420 回答