返回

MySQL WHERE 子句中使用 CASE 表达式实现用户参数查询

mysql

在 MySQL WHERE 子句中使用用户参数的 CASE 表达式

问题:未知列错误

我们经常需要根据用户输入的月份获取特定月份的所有日期。在 MySQL 中,我们通常使用 CASE 表达式将用户选择的月份文本值映射到相应的数字月值,然后在 WHERE 子句中使用这些数字月值。

但是,当我们直接使用月份文本值(例如 'January')在 CASE 表达式中进行比较时,MySQL 会返回错误 [42S22][1054] 未知的列 'January' 出现在 'where 子句' 中

解决方案:将文本值与数字月值比较

要解决此错误,我们必须将用户选择的月份文本值与 CASE 表达式中对应的数字月值进行比较。修改后的查询如下:

SELECT DISTINCT DAY(measurement_timestamp) AS timestamp
FROM my_table
WHERE EXTRACT(YEAR FROM measurement_timestamp) = ${Year}
  AND EXTRACT(MONTH FROM measurement_timestamp) = (CASE
                            WHEN ${Month} = 'January' THEN 1
                            WHEN ${Month} = 'February' THEN 2
                            WHEN ${Month} = 'March' THEN 3
                            WHEN ${Month} = 'April' THEN 4
                            WHEN ${Month} = 'May' THEN 5
                            WHEN ${Month} = 'June' THEN 6
                            WHEN ${Month} = 'July' THEN 7
                            WHEN ${Month} = 'August' THEN 8
                            WHEN ${Month} = 'September' THEN 9
                            WHEN ${Month} = 'October' THEN 10
                            WHEN ${Month} = 'November' THEN 11
                            WHEN ${Month} = 'December' THEN 12
                            ELSE NULL  -- 如果提供的月份文本值无效,则返回 NULL
    END)
ORDER BY timestamp DESC;

此修改后的查询将:

  1. 提取 measurement_timestamp 字段中的年份和月份。
  2. 将用户选择的月份文本值(例如 'January')与 CASE 表达式中的月份文本值进行比较。
  3. 如果找到匹配项,则返回相应的数字月值(例如 1)。
  4. 将数字月值与 measurement_timestamp 字段中提取的月份进行比较。
  5. 如果月份匹配,则返回该日期。
  6. 如果没有匹配项,则返回 NULL。

结论

通过将用户选择的月份文本值与 CASE 表达式中对应的数字月值进行比较,我们成功解决了未知列错误。现在,查询将按预期工作,并根据用户选择的月份文本值正确获取特定月份的所有日期。

常见问题解答

  1. 为什么直接比较月份文本值会引发错误?

    MySQL 中的 CASE 表达式使用列值或常量进行比较,而不是文本字符串。因此,直接比较月份文本值会导致未知列错误。

  2. 为什么我们需要在 CASE 表达式中处理无效的月份文本值?

    如果没有匹配项,MySQL 会将 CASE 表达式求值为 NULL。因此,在 CASE 表达式中包含 ELSE NULL 分支对于处理无效的月份文本值非常重要。

  3. 如何优化 CASE 表达式以提高性能?

    对于较长的 CASE 表达式,可以使用子查询或 JOIN 来提高性能。

  4. 如何在 Grafana 中处理用户参数?

    在 Grafana 中,可以使用变量来存储用户选择的月份文本值。然后,这些变量可以在 MySQL 查询中作为参数使用。

  5. 还有其他方法可以解决未知列错误吗?

    另一种方法是使用动态 SQL 来生成使用数字月值的查询。但是,此方法比 CASE 表达式方法更复杂。