2014-06-23 1 views
0

가 여기에 일치 받기 : 나는 데이터를 얻을 때내 쿼리를 열 및 그 값의 MySQL의

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

나는 그들이 검색 한 사용자에게 표시합니다. 이제는 ID, Name & Description 만 표시합니다. 또한 검색 문자열과 일치하는 열을 표시하려고합니다. 일치하는 경우 Status 행의 상태를 표시하고 다른 행과 일치하면 일치하는 열의 값을 표시하려고합니다.

여러 열과 일치하는지 여부는 중요하지 않습니다. 첫 번째 버전 만 필요합니다.

모든 열을 선택하지 않고이 경우 가능합니까 & 각 PHP 검색을 실행하여 일치하는 항목을 찾으십니까? MySQL에서 간단하게 수행 할 수 있습니까?

내 검색이 꽤 느려지고 더 많은 열을 내고 있습니다. & 더 많은 테이블을 검색에 추가 했으므로이 기능을 사용하면 많은 오버 헤드를 추가하지 않아도됩니다.

답변

1

는 ...에만 열을 반환

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 | 
+----+------+------+ 
+0

을 다음 고려, 나는 또한 열 – GGio

+0

그래로 값이 필요하지만, 이미 가치가 무엇인지! – Strawberry

+0

아니요. '%%'와 (과) 같은 값을 포함하고 있으므로 일치하는 실제 값이 필요합니다. – GGio

1

는이 같은 비트 messily 그것을 할 수 있습니다 : -

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 

다운면 당신이 (상당히 시간이 소요) 검사를 반복하는 것입니다. MySQL이이를 최적화 할 수 있는지 확실하지 않지만 그렇지 않다면 나를 놀라게하지는 않을 것입니다.

대안으로 각 조건에 대해 하나씩의 UNION 쿼리가있을 수 있습니다. 그런 다음이를 하위 쿼리로 사용하여 최대 값을 선택합니다.

UNION을 사용하면 이와 비슷한 효과를 얻을 수 있습니다. LIKE가 주요 와일드 카드를 사용하지 않는다고 가정 할 때 각 UNIONED 쿼리는 인덱스를 사용할 수있는 이점이 있습니다 (현재 쿼리는 서로 다른 OR 열을 함께 검사하여 일치를 얻을 수 없습니다).

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