【问题标题】:MySQL: Look for specific value first then get a second valueMySQL:首先查找特定值,然后获取第二个值
【发布时间】:2020-01-18 22:11:11
【问题描述】:

到目前为止我的代码

SELECT * FROM gp 
WHERE status IN ('priority', NULL)  
   AND (status='priority' OR EXISTS(SELECT * FROM gp WHERE status IS NULL)) 
LIMIT 1

我正在尝试使用status = 'priority' 获取第一行(如果存在),或者使用status = NULL 获取第一行。状态可能还有其他值,但我只想先获得priority(如果可用),然后是NULL

到目前为止,我的代码所做的是,当它们存在时,它返回带有 status = 'priority' 的行,但在仅存在 NULLs 时不返回任何内容。

【问题讨论】:

  • 如果我使用 ORDER BY,它必须是 DESC 才能在 NULL 之前获得“优先级”。但是使用 DESC,我也可以先获得最后一个“优先级”或 NULL。
  • 什么定义了“第一”行?
  • 它们被导入的顺序 - id 的顺序。正常的 ASC 顺序
  • 记住:根据定义,数据库表是无序的。如果您没有ORDER BYsomewhere,事情可能似乎会以稳定、合理的排序顺序返回,但这只是因为它对数据库很方便现在。然后有一天,您可以添加一个新索引,或者一个补丁添加了您在其他数据库中看到的循环性能优化,或者维护工作重新排序磁盘上的页面。突然之间,旧的排序不再是最方便的选择,您的查询中断了。或者更确切地说,您发现您的查询总是被破坏,而您只是侥幸逃脱。
  • 第二部分。我看到了这个:The order they were imported in - order of the id's。这也是不可靠。有些东西可以改变这些 ID 的默认顺序。如果这个顺序真的很重要,您应该考虑添加一列来捕获创建记录时的时间戳。

标签: mysql sql sql-order-by


【解决方案1】:

您不能在IN 表达式中使用NULL,因此您需要将WHERE 子句的第一部分更改为

WHERE status = 'priority' OR status IS NULL

您可以删除WHERE 子句的第二部分并简单地

ORDER BY status = 'priority` DESC

这会将具有status = 'priority' 的行放在具有statusNULL 的行之前

所以你的查询作为一个整体变成:

SELECT * FROM gp 
WHERE status = 'priority' OR status IS NULL
ORDER BY status = 'priority` DESC
LIMIT 1

请注意,要获得带有 status = 'priority' 的“第一”行,您需要一个排序列(SQL 表是无序的,因此没有排序列“第一”没有意义),您可以将其添加到 ORDER BY子句:

SELECT * FROM gp 
WHERE status = 'priority' OR status IS NULL
ORDER BY status = 'priority` DESC, id ASC
LIMIT 1

【讨论】:

  • 这会将最后的记录放在任一类型的首位。我想获得每一个中的第一个。
  • @nieburr 没有列排序的“第一”没有真正的定义;看我的编辑。您是否有一个 id 列或类似的列来定义“第一”是什么?
  • @nieburr 我已经通过将id 添加到ORDER BY 子句来更新答案;这将为您提供任一类型的“第一”行
  • @nieburr 不用担心 - 我很高兴能帮上忙
猜你喜欢
  • 1970-01-01
  • 2016-10-26
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 2017-10-16
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
相关资源
最近更新 更多