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


「魚」、「願い」、「確かに」、または「ええ」 --- SELECT flow.node_id1

  • これは、"fish"、"wish"、および "*yes*" がすべて 1 に関連付けられているflow.node_idためです。 *yes* はアスタリスクで囲まれているため、"yes" が文字どおりに解釈されるのではなく、 から値が引き出されることに注意してくださいplaceholder_variables

「いいえ」または「いいえ」 --- SELECT flow.node_id2

  • これは、"*no*" と "nay" が 2 に関連付けられているflow.node_idためです。繰り返しますが、アスタリスクがあるため、"no" は文字どおりには解釈されませんが、"nope placeholder_variables" "はflow_strings表にありません。

「いいえ」と「*いいえ*」--- 一致しません

*no* が に含まれflow_stringsていても、アスタリスク (および対応する placeholder_variable) がアスタリスクで囲まれているため、一致しないはずです。これは、文字どおりに解釈されるべきではなく、対応するプレースホルダー変数の値によってのみ評価できることを意味します。


「赤ちゃん」 ---一致しません

  • 「baby」にはアスタリスクが付いていませんが、flow.node_id3 に対応し、そのノードのノードflow.sourceは 1 です。

"derp" ---一致しません

  • これは、テーブルplaceholder_variables.sourceにあるにもかかわらず、*herp* が 1 であるためです。flow_strings

"*herp*" --- SELECT flow.node_id4

  • 表の *herp* の周りにアスタリスクがありますがflow_strings、対応するのplaceholder_variable.sourceは 1 です。

** 総括する **

  1. いいえsource= 1
  2. sql_regexがアスタリスクで囲まれている場合、placeholder_variables を解釈しますが、対応する placeholder_variablesourceが 0 の場合のみです。
  3. sourceが 0 で、アスタリスクが存在しない場合は、sql_regex文字どおりに解釈します。

MySQL を使用SUBSTRING()してアスタリスクを操作できることはわかっています。また、(PHP を使用しているため) 理論的にはこれを 2 つのクエリに分割し、最初のクエリをループして 2 番目のクエリを動的に生成できることも知っています。ただし、これは 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 に答える