【问题标题】:Returning the column name(s) where a search term is found, using PHP使用 PHP 返回找到搜索词的列名
【发布时间】:2014-03-29 19:57:54
【问题描述】:

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

【问题讨论】:

  • 如果在多个字段中找到该字符串会发生什么?
  • @TheWolf -- 理想情况下,它将显示每个字段的出现。

标签: mysql sql search


【解决方案1】:

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

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)
         ... 
       )

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

【讨论】:

  • 我看到这对于少数固定字段是如何工作的,但希望找到一些动态的东西,这样它就可以适应添加的新字段,而无需手动更新 SQL。我会将其添加到我的原始帖子中。
【解决方案2】:

使用联合:

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 ;

【讨论】:

  • 这需要我一点时间来消化。谢谢。
猜你喜欢
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多