简体   繁体   English

获取匹配的列及其值MySQL

[英]Get matching column & its value MySQL

Here is my query: 这是我的查询:

SELECT ID, Name, Description
FROM MyTable
WHERE NAME LIKE :search OR Description LIKE '%search%' 
      OR Status LIKE '%search%'
      OR ... Many Other Columns LIKE '%search%

When I get the data I display it to the user that they searched for. 当我得到数据时,将其显示给他们搜索的用户。 Now I only display ID, Name & Description . 现在,我只显示ID, Name & Description I also want to display which column matched the searching string. 我还想显示匹配搜索字符串的列。 If it matched Status I want to display the status of the row, if it matched any other column I want to display the value of that column that it matched. 如果匹配Status我想显示行的状态,如果匹配其他任何列,我想显示匹配的那列的值。

Does not matter if it matches multiple columns. 匹配多个列无关紧要。 I only need the first one. 我只需要第一个。

Is this possible without selecting all columns & then running PHP search on each to find out which one matched? 是否可以不选择所有列,然后在每个列上运行PHP搜索来找出匹配的列呢? Can it be done simply in MySQL? 可以简单地在MySQL中完成吗?

I want to make it as fast as possible since my search is becoming pretty slow the more columns & more tables I add to the search and do not want this feature to add a lot of overhead. 我想使速度尽可能快,因为我向搜索添加的列和表格越多,搜索就会变得越来越慢,并且不希望此功能增加很多开销。

You can do it a bit messily like this:- 您可以像这样杂乱地做它:-

SELECT ID, 
        Name, 
        Description,
        CASE
            WHEN NAME LIKE :search THEN 'NAME'
            WHEN Description LIKE :search THEN 'Description' 
            WHEN Status LIKE :search THEN 'Status' 
            ... Many Other Columns LIKE :search
            ELSE 'Unknown Column'
        END AS MatchingColumn
FROM MyTable
WHERE NAME LIKE :search OR Description LIKE :search OR Status LIKE :search OR 
      ... Many Other Columns LIKE :search

Down side is that you are repeating the (fairly time consuming) checks. 不利的一面是您要重复(非常耗时)检查。 Not sure if MySQL manages to optimise these away, but it wouldn't surprise me if not. 不知道MySQL是否设法优化了这些,但是如果没有,这也不会令我感到惊讶。

Alternative might be do a UNION of queries, one for each condition. 另一种可能是执行查询的UNION,每个条件一个。 Then use this as a sub query to select the max from. 然后将其用作子查询以选择最大值。

Using UNION would give you something like this. 使用UNION将为您提供类似的信息。 It does have the benefit that each UNIONed query can then use indexes (your current query can't as you are checking different columns ORed together to get a match), assuming the LIKE doesn't use a leading wildcard. 这样做的好处是,假设LIKE不使用前导通配符,则每个UNIONed查询随后都可以使用索引(当您查询不同的列时,当前查询不能使用ORed来获得匹配项)。

SELECT ID, Name, Description, MAX(MatchingColumn)
FROM
(
    SELECT ID, Name, Description, 'NAME' AS MatchingColumn
    FROM MyTable
    WHERE NAME LIKE :search
    UNION
    SELECT ID, Name, Description, 'Description' AS MatchingColumn
    FROM MyTable
    WHERE Description LIKE :search
    UNION
    SELECT ID, Name, Description, 'Status' AS MatchingColumn
    FROM MyTable
    WHERE Status LIKE :search OR 
) sub0
GROUP BY ID, Name, Description

Consider the following... 考虑以下...

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, a INT NOT NULL, b INT NOT NULL, c INT NOT NULL);

INSERT INTO my_table (a,b,c) VALUES 
(101,102,103),
(102,103,104),
(103,104,105),
(104,105,106),
(105,106,107);

 SELECT * FROM my_table;
+----+-----+-----+-----+
| id | a   | b   | c   |
+----+-----+-----+-----+
|  1 | 101 | 102 | 103 |
|  2 | 102 | 103 | 104 |
|  3 | 103 | 104 | 105 |
|  4 | 104 | 105 | 106 |
|  5 | 105 | 106 | 107 |
+----+-----+-----+-----+

SELECT id
     , CASE WHEN a LIKE '%04%' THEN 'a' WHEN b LIKE '%04%' THEN 'b' WHEN c LIKE '%04%' THEN 'c' END col 
     , CASE WHEN a LIKE '%04%' THEN a WHEN b LIKE '%04%' THEN b WHEN c LIKE '%04%' THEN c END val 
  FROM my_table;
+----+------+------+
| id | col  | val  |
+----+------+------+
|  1 | NULL | NULL |
|  2 | c    |  104 |
|  3 | b    |  104 |
|  4 | a    |  104 |
|  5 | NULL | NULL |
+----+------+------+

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM