使用PHP返回找到搜索词的列名

时间:2014-03-29 19:57:55

标签: mysql sql search

示例:我有一个包含5个字段的表,名为id,field_1,field_2,field_3,field_4 而我正在寻找' foo'在所有领域。

SELECT ID FROM table WHERE field_1 LIKE ('%foo%') OR field_2 LIKE ('%foo%') OR ...

我想要返回ID,以及找到该字词的字段。

最有效的方法是什么?

注意:我正在寻找一种可以动态适应添加新数据库字段的解决方案,而无需手动更新SQL。

2 个答案:

答案 0 :(得分:2)

一种可能的方法是在返回的列中映射这些匹配项:

SELECT ID, 
       field_1 LIKE '%foo%' AS field_1_match,
       field_2 LIKE '%foo%' AS field_2_match
...

...所以你可以检查每个相应的column_match值,以便知道它是否匹配。

很容易将此扩展为返回包含列的字符串(例如,由,分隔)和CONCAT_WS

SELECT ID, 
       CONCAT_WS(',',
         IF(field_1 LIKE '%foo%', 'field_1', NULL),
         IF(field_2 LIKE '%foo%', 'field_2', NULL)
         ... 
       )

...但是,老实说,我怀疑以这种方式处理数据会更容易。

答案 1 :(得分:0)

使用工会:

SELECT id, 'field_1' as 'fieldName' FROM table WHERE field1 LIKE '%foo%' UNION
SELECT id, 'field_2' as 'fieldName' FROM table WHERE field2 LIKE '%foo%' UNION
...

这将在任何位置返回id和列名称。如果它在同一行上多次发生,则将为该行返回多个结果。

更新:

可以使用存储过程和游标动态搜索所有表。

DELIMITER //

CREATE PROCEDURE search_all_fields(IN search VARCHAR(100), IN tableName VARCHAR(100), IN idColumnName VARCHAR(100)) 
BEGIN

    DECLARE sqlQuery VARCHAR(200);
    DECLARE done INT DEFAULT 0;
    DECLARE columnName VARCHAR(30);
    DECLARE cur CURSOR FOR SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_NAME`= tableName; # cursor will iterate over the column names
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
    CREATE TEMPORARY TABLE temp ( id VARCHAR(100), FieldName VARCHAR(100) ); # procedure returns multiple result sets, so we'll dump them in a temp table and get them at the end
    OPEN cur;

    read_loop: LOOP # iterates through column names
        FETCH cur INTO columnName;
        IF done THEN
            LEAVE read_loop;
        END IF;

        # execute search
        SET @sqlQuery = CONCAT("INSERT INTO temp SELECT ", idColumnName, ", '", columnName, "' as 'FieldName' FROM ", tableName, " WHERE ", columnName, " LIKE '%", search, "%'");
        PREPARE stmt FROM @sqlQuery;
        EXECUTE stmt;
    END LOOP;

    CLOSE cur;
    # grab the results
    SELECT * FROM temp;
END;//

DELIMITER ;