2012-12-13 47 views
1

我有一个VIEW,其中包含4列,我基本上用作全文搜索。用户输入一个字符串转换为文本框,它会查询,像这样的观点:MySQL获取匹配WHERE子句的列名称

SELECT * FROM vw_clients WHERE 
col1 = "'%".$userInput."%'" 
OR col2 = "'%".$userInput."%'" 
OR col3 = "'%".$userInput."%'" 
OR col4 = "'%".$userInput."%'" 

我的结果正确返回,但有一种方法来确定哪些列包含搜索词?通过MySQL还是PHP?

+4

这不是全文搜索。这是旧的学校搜索与不正确的语法。 –

+0

列值将包含前导和后缀'%'字符有点奇怪。它看起来像“=”比较运算符实际上是一个LIKE比较运算符。而且我还会包含必要的注意事项,这似乎很容易受到SQL注入的影响。 – spencer7593

回答

4

不能直接在MySQL,但也有极其丑陋的黑客:

SELECT col1, (col1 LIKE '%$userinput%') AS found_in_col1, 
    col2, (col2 LIKE '%$userinput%') AS found_in_col2, 
    etc... 
etc... 
WHERE ... 
在PHP

,这将会是循环遍历结果集中的领域,做一个strpos()检查的问题。无论哪种方式......丑陋。

+0

是的,我喜欢那样。有时候,肮脏是唯一的出路。 –

+0

我想你可以把它包装在'CASE ... WHEN ... END'中,这样你只有一列。 –

2
SELECT 
     *, 
     CONCAT_WS(',', 
     IF(col1 = "'%".$userInput."%'",'col1',NULL), 
     IF(col2 = "'%".$userInput."%'",'col2',NULL), 
     IF(col3 = "'%".$userInput."%'",'col3',NULL), 
     IF(col4 = "'%".$userInput."%'",'col4',NULL)) as colmatches 
    FROM .... 
1

还有一个丑陋的方法:使用 “案例” 或 “如果” 中选择查询:

SELECT CASE WHEN col1='%value%' THEN 'col1' WHEN col2='%value%' THEN 'col2' END as found_column 
FROM .... 
WHERE .... 
0

事情是这样的:

SELECT IFNULL(v.col1 LIKE CONCAT('%','$userInput','%'),0) AS col1_match 
    , IFNULL(v.col2 LIKE CONCAT('%','$userInput','%'),0) AS col2_match 
    , IFNULL(v.col3 LIKE CONCAT('%','$userInput','%'),0) AS col3_match 
    , IFNULL(v.col4 LIKE CONCAT('%','$userInput','%'),0) AS col4_match 
    , v.* 
    FROM vw_clients v 
WHERE v.col1 LIKE CONCAT('%','$userInput','%') = 1 
    OR v.col2 LIKE CONCAT('%','$userInput','%') = 1 
    OR v.col3 LIKE CONCAT('%','$userInput','%') = 1 
    OR v.col4 LIKE CONCAT('%','$userInput','%') = 1 

注:这个构造容易受到SQL注入的影响;它取决于不包含SQL结构的$userInput。例如

$userInput = "foo')=1 OR '1' LIKE CONCAT('1";