总结大量 CASE WHEN 的最佳方式

Posted

技术标签:

【中文标题】总结大量 CASE WHEN 的最佳方式【英文标题】:Best way to summarize a huge list of CASE WHEN 【发布时间】:2020-07-10 20:15:54 【问题描述】:

假设我有一个带有字符串的表,并且我想通过将不同的字符串分组到“类别”中来创建该表的聚合。 为了了解将每个字符串分配给哪个类别,我有一个可能性列表,我可以总结如下:

CASE WHEN string = 'aaa' THEN 'cat_aaa'

CASE WHEN string = 'bbb' THEN 'cat_bbb'

[...]

CASE WHEN string LIKE '%abc%' THEN 'cat_abc'

现在,列表可能非常庞大并且可能需要更新,所以我不想制作一个无限的 CASE WHEN 列表。我希望有一个表格,其中包含用于比较的字符串和相应的类别。

所以让我们假设有一个包含所有字符串的第一个表:

TABLE A
=======
string
--------
aaa
bbb
aaa
aaa
aaa
dabc
fabc
------

还有一张桌子

TABLE B
=======
string_comparison | category
      aaa         | cat_aaa
      bbb         | cat_bbb
     %abc%        | cat_abc

如果它们都是 = 条件,我可以加入两个字符串。但是,根据 string_comparison 的类型,我可能需要执行 LIKE 比较。 您对如何解决这种情况有什么新想法吗?由于表演,我不想在 LIKE 的基础上加入这两张桌子。有没有可能在字符串上使用正则表达式来解决这个问题?

我正在使用红移。

【问题讨论】:

我删除了不一致的数据库标签。请标记您真正使用的数据库。 如果这是我的要求,我会推迟在数据库中执行此操作,但如果我不得不这样做,我想我会有一个包含 3 列 MATCH_OPERATOR 的表(例如,等于、startsWith、endsWith)、MATCH_TEXT(您的字符串比较,不带 % 符号)和 CATEGORY,然后根据需要使用子选择来获取类别。如果他们认为这是一个糟糕的想法,其他人可以发表评论 =) @Nikki9696 您将如何以不同的方式处理这种情况?考虑我的输入是我的数据库表中已经存在的初始字符串。然后我可以使用 string_comparison 和关联的类别创建我喜欢的输入。一张表对我来说听起来不错,但由于我们无法匹配任何可能的 string_comparison 我考虑了 LIKE 解决方案 @wellaDIN 我通常不喜欢将业务逻辑与持久性数据层混合。我会以不同的方式存储它(需要分析)并使用业务层(应用程序代码)像你一样创建字符串。我知道这种方法并不适用于所有情况,所以如果它不适用于您的最终目标,那么我会使用我在之前评论中提到的内容。 【参考方案1】:

没有通配符的like 实际上与= 相同,任何合理的优化器都应该正确处理它,所以我不会想太多而只是尝试加入like

SELECT   category, COUNT(*)
FROM     a
JOIN     b ON string LIKE string_comparison
GROUP BY category

如果您真的担心 like 运算符的性能,您可以尝试检查 string_comparison 中是否没有通配符并将其短路,但我怀疑它会不会比直接使用like 更快:

SELECT   category, COUNT(*)
FROM     a
JOIN     b ON (POSITION('%' IN string_comparison) > 0 AND
               POSITION('_' IN string_comparison) > 0 AND 
               string LIKE string_coparison) OR
              string = string_comparison
GROUP BY category

注意:您没有使用您正在使用的 RDBMS 标记问题,因此我使用 Postgresql 的 position 函数给出了一个示例。其他 RDBMS 应该具有具有相同功能的功能,尽管它们的名称可能不同。

【讨论】:

这听起来很酷。但是,使用 LIKE 运算符让我害怕的另一件事是它可能(即使这不应该)给我更多的行,而 EQUALS 不会(假设 string_comparison 是表 B 的关键)。你认为有办法处理这种情况和可能的重复吗?

以上是关于总结大量 CASE WHEN 的最佳方式的主要内容,如果未能解决你的问题,请参考以下文章

条件判断函数-CASE WHEN、IF、IFNULL详解

每个 'when' 块中具有多个值的 case 语句

今日总结(linux和sql)

数据库复习总结(16)-case关键字(数据透视)

数据库之Case When

使用 partition by 和 case when