所以,我有一个令人困惑的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
,这就是我需要发生的事情。
“fish”,“wish”,“sure”或“yeah” --- SELECT flow.node_id
1
flow.node_id
相关联。注意* yes *被星号包围,所以不是“是”而是字面解释,它改为从placeholder_variables
。 “nope”或“nay” --- SELECT flow.node_id
2
flow.node_id
相关联2.再次,由于星号,“no”不按字面解释,但“nope”匹配,因为“no”是在placeholder_variables
表格中,即使“{1}}表格中没有”nope“。“no”和“* no *” --- NO MATCH
即使* * *在flow_strings
中,它也不应该匹配,因为它周围有星号(以及相应的占位符_变量),这意味着它不应按字面解释,因此只能通过其相应的方式进行评估占位符变量的值。
“baby” --- NO MATCH
flow_strings
3,而该节点的flow.node_id
为1。“derp” --- NO MATCH
flow.source
对于* herp *是1,即使它在placeholder_variables.source
表中。 “* herp *” --- SELECT flow_strings
4
flow.node_id
表中的* herp *周围有星号,相应的flow_strings
也是1。**总结**
placeholder_variable.source
= 1 source
被星号包围,则解释占位符_变量,但仅当相应的placeholder_variable的sql_regex
为0时才解释。source
为0,且没有星号,则按字面解释source
。我知道我可以使用MySQL的sql_regex
来处理星号。我也知道,(因为我正在使用PHP)我理论上可以将它分成两个查询,然后通过循环第一个来动态生成第二个查询。然而,这将是A)记忆密集型和B)草率。
所以我的问题是:单独使用MySQL是否可以做到这一点?如果是的话,你会如何推荐我格式化它?你不需要为我编写查询,但如果你能帮助我解决一些逻辑,我将非常感激!除了我已经概述的内容之外,我完全不知道该尝试什么,我绝对不想那样做。
谢谢!
答案 0 :(得分: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.