【问题标题】:How to select only the first elements satisfying a condition?如何仅选择满足条件的第一个元素?
【发布时间】:2015-07-09 21:27:28
【问题描述】:

我有下表(实际问题的简化):

+----+-------+
| id | value |
+----+-------+
|  1 | T     |
|  2 | T     |
|  3 | F     |
|  4 | T     |
+----+-------+

现在,一个简单的SELECT id FROM Table WHERE value='T'; 会为我提供值为 T 的所有 ID,但在上面的示例中,我只需要前 2 个(1 和 2)。

最好的方法是什么?我不想使用 while 循环。

我将它标记为 MySQL,但适用于大多数数据库引擎的解决方案会更好。

编辑:根据答案,我可能还不够清楚:
我只想要值为“T”的第一个 ID。这可以是从没有值到所有值的任何值。

编辑 2:另一个例子:

+----+-------+
| id | value |
+----+-------+
|  1 | F     |
|  2 | T     |
|  5 | T     |
|  6 | F     |
|  7 | T     |
|  9 | T     |
+----+-------+

结果将是 []。

示例 3:

+----+-------+
| id | value |
+----+-------+
|  1 | T     |
|  2 | T     |
|  5 | T     |
|  6 | F     |
|  7 | T     |
|  9 | T     |
+----+-------+

结果:[1, 2, 5]

【问题讨论】:

  • 我已经根据您的更新要求更新了我的答案。

标签: mysql sql while-loop ansi-sql


【解决方案1】:

你在追求这么简单的事情吗?只是限制结果?

select id from table where value = 'T' order by id asc limit 2

如果出于某种原因您想要最后两场比赛而不是前两场比赛,只需将顺序更改为 desc 而不是 asc

我看到标准发生了一些变化。

select id
  from `table` t
    where t.id >= (select @min := min(id) from `table` t2 where value = 'T') 
      and not exists (select id from `table` t3 where value = 'F' and id > @min and id < t.id)
   and value = 'T'

demo here

如果在第一个值为 'F' 时不希望有任何结果,那么这个:

select id
  from `table` t
    where 
       not exists (select id from `table` t3 where value = 'F' and id < t.id)
   and value = 'T'

【讨论】:

  • 我认为他不需要排序或排序
  • 没有排序,'前两个'没有意义。而且由于他特别要求 id 最低的值,所以排序是合适的
  • 我假设 id 会自动递增,因为我们将 PK 的默认值设置为自动递增。
  • @DanyalSandeelo - 即使 PK 是一个 AUTOINCREMENT 字段,仍然没有 保证 LIMIT 2 将返回哪些行也使用ORDER BY。确实,在现实中你通常按PK顺序得到结果,但是没有不能保证
  • @DanyalSandeelo 读到:forums.mysql.com/read.php?21,239471,239688#msg-239688。如果你想订购,你必须使用order by,否则虽然它看起来可以工作,但它有可能会停止
【解决方案2】:

如果 ID 是自动递增的,则可以使用 order by limit

select * from table_name where value = 'T' order by id limit 2

【讨论】:

  • 感谢您的回答。请看我的编辑。我可能还不够清楚。
  • 您能否提供更多示例,如果我从给定示例中正确理解1,2 正在保存T 然后3 是'F',后跟4T 如此一旦它以不同的值达到 3,它应该停止是您正在查看的内容吗?如果是这样,如果你有 5T 等等会发生什么?
  • @pala_ 如果 id 重复,那么它相当清楚,即第一个 id 值为 T 但如果它们没有重复,那么可能需要重新访问。
  • 我的解释是他想要 T 值的第一个窗口,无论它出现在哪里。
  • @AbhikChakraborty:是的。我想要 'id' 的前 N ​​个值,其中值为 'T'。
【解决方案3】:

如果您不需要对数据进行任何排序或排序

  SELECT id FROM Table WHERE value='T' limit 0,2

如果您想按 id 订购,您可能需要添加“ORDER BY”。例如

SELECT id FROM Table WHERE value='T' order by id limit 0,2

【讨论】:

    【解决方案4】:

    您可以获取“F”第一次出现的 id,然后在条件中使用。
    你可以这样做:

    SELECT id FROM tables where id < (select AVG(id) FROM tables WHERE value = 'F' ORDER BY id LIMIT 1)
    

    【讨论】:

    • 你使用AVG(id)意图是什么?如果表末尾有三个记录 F 怎么办?说 id 的 98、99 和 100。AVG(id) 返回 99,这意味着您的外部查询将包括第 98 行,如果是 F 和 OP 并且想要 Ts。这对我来说似乎没有任何意义。
    • 如果记录是{F, F, F, T, T}怎么办?然后您的查询返回第一个 F 而没有一个 Ts...
    • @MatBailie,这就是记录限制为 1 的原因,我只是假设即使只有 1 条记录,查询也会返回一个集合。我并不是说获取 ids 的平均值是正确的方法。可能有更好的方法,但想法是获取 id 并在条件下使用。
    • 聚合应用于之后 WHERE之前 ORDER BYLIMIT。因此,您正在获得 all F 记录的平均 id。
    【解决方案5】:

    尝试如下LIMIT 2

    SELECT id 
    FROM Table 
    WHERE value='T'
    ORDER BY id
    LIMIT 2
    

    【讨论】:

      猜你喜欢
      • 2013-04-08
      • 1970-01-01
      • 2020-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-06
      相关资源
      最近更新 更多