【问题标题】:SQL: How to select a single row based on a column matched against multiple possible values with preferred match order?SQL:如何根据与具有首选匹配顺序的多个可能值匹配的列来选择单行?
【发布时间】:2021-08-19 19:55:02
【问题描述】:

使用 MariaDB。

假设您有一张表,其中一列是 color,并且是主键,因此它是唯一的。

我想要一个 select 语句根据颜色获取一行,但我想按首选顺序搜索三种可能的颜色匹配。

普通的WHERE color='red' OR color='blue' OR color='green' 不起作用,因为它会返回多行。我不能使用ORDER BYLIMIT,因为这三个搜索值不是按字母顺序排列的。

我想搜索color='red',如果有红色,就给我那一行。如果没有红色,请给我color='blue' 的行。如果没有红色或蓝色,请给我color='green' 的行。但要明确一点,在搜索第一种颜色红色时,即使有蓝色和绿色也只会返回红色,因为它是首选匹配。但是如果没有红色,则下一个颜色为蓝色。

我查看了if()IF...THENCASE,但不知道该怎么做。有什么办法吗?

【问题讨论】:

    标签: mysql sql mariadb


    【解决方案1】:

    您可以使用ORDER BY 子句和LIMIT 1

    WHERE color='red' OR color='blue' OR color='green'
    ORDER BY color='red' DESC, 
             color='blue' DESC,
             color='green' DESC -- not actually needed
    LIMIT 1;
    

    MySql 和 Mariadb 将诸如 color='red' 之类的布尔表达式计算为 1 代表 true0 代表 false,因此当您按 color='red' DESC 排序时,返回 1 的行(带有 color='red' 的行)将排在首位,其他所有人次之。

    或者,使用CASE 表达式:

    WHERE color='red' OR color='blue' OR color='green'
    ORDER BY CASE color
      WHEN 'red' THEN 1
      WHEN 'blue' THEN 2
      WHEN 'green' THEN 3
    END
    LIMIT 1;
    

    【讨论】:

    • 两个答案(按 vs union 排序)看起来都可行,但我不确定哪个有更好的性能。但是,我更喜欢 order by 的外观,并且我假设 order by 的工作量比工会少,所以我会接受这个答案。谢谢。
    【解决方案2】:
    select *
    from (
        select *, 1 as Rank from MyTable where color = 'red'
        union all
        select *, 2 as Rank from MyTable where color = 'blue'
        union all
        select *, 3 as Rank from MyTable where color = 'green'
    ) x
    order by Rank
    limit 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-15
      • 1970-01-01
      • 2020-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多