示例:我有一个包含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。
答案 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 ;