2

所以,我有一个令人困惑的 MySQL 问题。我觉得我需要使用一些 IF 语句,但我真的不确定如何在这种情况下实现它们!首先,考虑以下查询。这很简单:

SELECT *
FROM flow
INNER JOIN flow_strings
    USING(node_id)
WHERE
    (
        flow.parent = 0
        OR flow.parent = :user_flow
    )
    AND flow.source = 0
    AND :input LIKE flow_strings.sql_regex

但是,我需要扩展它,这就是我卡住的地方。考虑到这一点,我不确定如何解释它,所以下面是表结构,然后是一些示例。

桌子flow

+---------+--------+--------+
| node_id | parent | source |
+---------+--------+--------+
|    1    |   0    |    0   |
+---------+--------+--------+
|    2    |   0    |    0   |
+---------+--------+--------+
|    3    |   1    |    1   |
+---------+--------+--------+
|    4    |   3    |    0   |
+---------+--------+--------+

桌子flow_strings

+----------------+---------+-----------+
| flow_string_id | node_id | sql_regex |
+----------------+---------+-----------+
|        1       |    1    |   fish    |
+----------------+---------+-----------+
|        2       |    1    |   wish    |
+----------------+---------+-----------+
|        3       |    1    |   *yes*   |
+----------------+---------+-----------+
|        4       |    2    |   *no*    |
+----------------+---------+-----------+
|        5       |    2    |   nay     |
+----------------+---------+-----------+
|        6       |    3    |   *herp*  |
+----------------+---------+-----------+

[ ... ]

桌子placeholder_variables

+-------------+--------+------+-------+
| variable_id | source | name | value |
+-------------+--------+------+-------+
|      1      |    0   | yes  | sure  |
+-------------+--------+------+-------+
|      2      |    0   | yes  | yeah  |
+-------------+--------+------+-------+
|      3      |    0   | no   | nope  |
+-------------+--------+------+-------+
|      4      |    1   | herp | derp  |
+-------------+--------+------+-------+

现在,这就是我需要基于:input.


“鱼”、“愿望”、“确定”或“是” ——选择flow.node_id1

  • 这是因为“fish”、“wish”和“*yes*”都与flow.node_id1 相关联。请注意,*yes* 被星号包围,因此“yes”不是按字面解释,而是从placeholder_variables.

“不”或“不” ——选择flow.node_id2

  • 这是因为“*no*”和“nay”与flow.node_id2 相关联。同样,由于星号,“no”不是按字面解释的,但“nope”匹配因为“no”在placeholder_variables表中,即使“nope” "不在flow_strings表中。

"no" 和 "*no*" ---不匹配

即使 *no* is in flow_strings,它也不应该匹配,因为它周围有星号(以及相应的 placeholder_variable),这意味着它不应按字面解释,因此只能通过其相应的占位符变量的值来评估。


“宝贝” ——不匹配

  • 尽管“baby”周围没有星号,但它对应于flow.node_id3,并且该节点的flow.source为 1。

"derp" ---不匹配

  • 这是因为placeholder_variables.source*herp* 为 1,即使它在flow_strings表中。

"*herp*" ---选择flow.node_id4

  • 尽管flow_strings表中 *herp* 周围有星号,但对应placeholder_variable.source的是 1。

** 总结一下 **

  1. source= 1
  2. 如果 被星号包围,则解释 placeholder_variables sql_regex,但前提是相应的 placeholder_variablesource为 0。
  3. 如果source为 0,并且不存在星号,则按sql_regex字面意思解释。

我知道我可以使用 MySQLSUBSTRING()来处理星号。我也知道,(因为我正在使用 PHP)理论上我可以将其拆分为两个查询,然后通过循环第一个查询来动态生成第二个查询。但是,这将是 A)内存密集型和 B)草率。

所以我的问题是:是否可以单独使用 MySQL 来做到这一点?如果是,你会建议我如何格式化它?您不需要为我编写查询,但如果您能帮助我了解一些逻辑,我将非常感激!除了我已经概述的内容之外,我完全不知道该尝试什么,而且我绝对不想这样做。

谢谢!

4

1 回答 1

4

您可以使用此解决方案:

SELECT    a.*,
          COALESCE(c.value, b.sql_regex) AS string #-- If there was a successful JOIN (sql_regex was a variable), then display the value of the "value" column in placeholder_variables, otherwise if the JOIN did not succeed (sql_regex was a literal value), just display sql_regex instead.
FROM      flow a
JOIN      flow_strings b ON a.node_id = b.node_id
LEFT JOIN placeholder_variables c #-- LEFT JOIN placeholder_variables on these conditions:
       ON b.sql_regex LIKE '*%*' AND -- That sql_regex is a variable
          REPLACE(b.sql_regex, '*', '') = c.name AND -- Match sql_regex up with the "name" column in placeholder_variables. We must replace the asterisks in sql_regex so that the values can match ("name" column do not contain asterisks)
          c.source = 0
WHERE     a.source = 0 AND
          COALESCE(c.value, b.sql_regex) = :input -- If the string was interpreted as a placeholder variable, make the condition on the interpreted value in the placeholder_variables table ("name" column), otherwise, just make the condition on the sql_regex column.

SQLFiddle 演示

于 2012-08-04T20:31:26.830 回答