2015-12-21 67 views
0

我已經在我的數據庫表中獲得了一千萬記錄。 當我使用是非常緩慢,當我使用匹配他們失去了一些記錄。MySQL - 替代類似 - regexp?

我創建幫助表:

tag_list

tag_id 
tag_name 

tag_rel_message

tag_id 
messag_id 

消息

message_id 
message_text 

in tag_list我添加了所有單詞$ message_text - explode(「」,$ message_text);

我的新查詢:

SELECT m.* 
FROM tag_rel_messages trm 
INNER JOIN messages m ON (trm.message_id = m.message_id) 
INNER JOIN tag_list tl ON (trm.tag_id=tl.tag_id 
WHERE tl.tag_name REGEXP 'pionas' AND tl.tag_name REGEXP 'website' 
GROUP By trm.message_id 

但不顯示任何記錄。

這個查詢有什麼問題? 也許我應該使用REGEXP以外的東西?

感謝您的幫助

+0

如果我理解正確的話,tag_list的'tag_name'只包含單個標記關鍵字,那麼怎麼可能任何一個令牌同時匹配'pionas'和'網站'? – Fabricator

+0

是的,只有一個關鍵字。你是對的。那麼我應該怎麼做才能在所有條件都成立的情況下找到這條信息呢? – Pionas

+0

您的'WHERE'子句指出'tag_name'需要匹配''pionas''和**''website''。也許嘗試'OR'而不是'AND'? –

回答

0
$words = array('pionas', 'website'); 
$tags_id = array(); 
foreach ($words as $key => $val) { 
    $sql = "SELECT tag_id FROM tag_list WHERE tag_name LIKE '%".$val."%'"; 
    $records = $db->query($sql); 
    $tags_id[$key] = array_column($records, "tag_id"); 
} 

$inner_array = array(); 
foreach ($tags_id as $k => $v) { 
    $short_name = "trm_".$k; 
    $inner_array[] = " INNER JOIN tag_rel_message as ".$short_name." ON (".$short_name.".message_id = m.message_id AND ".$short_name.".tag_id IN (".implode(", ", $v).")) "; 
} 

$sql = "SELECT DISTINCT m.* FROM messages m".implode(" ", $inner_array); 

我覺得這是相同的:

SELECT * FROM messages WHERE message_text like '%pionas%' AND message_text like '%website%' 
0

我不知道一列如何能同時滿足兩件事情!您可以使用OR代替AND,也可以使用REGEXP的單個呼叫。

SELECT m.* 
FROM tag_rel_messages trm 
INNER JOIN messages m ON (trm.message_id = m.message_id) 
INNER JOIN tag_list tl ON (trm.tag_id=tl.tag_id 
WHERE tl.tag_name REGEXP 'pionas|website' 
GROUP By trm.message_id 
0

您需要用tag_listtag_rel_message表參加兩次匹配兩個不同的標籤。

SELECT m.* 
FROM messages AS m 
JOIN tag_rel_messages AS trm1 ON m.message_id = trm1.message_id 
JOIN tag_list AS t1 ON t1.tag_id = trm1.tag_id 
JOIN tag_rel_messages AS trm2 ON m.message_id = trm2.message_id 
JOIN tag_list AS t2 on t2.tag_id = trm2.tag_id 
WHERE t1.tag_name = 'pionas' AND t2.tag_name = 'website' 

另一種方法是使用上面的標籤加入,並計算結果的數量每封郵件

SELECT m.* 
FROM messages AS m 
JOIN tag_rel_messages AS trm ON m.message_id = trm.message_id 
JOIN tag_list AS t ON t1.tag_id = trm.tag_id 
WHERE t.tag_name IN ('pionas', 'website') 
GROUP BY m.message_id 
HAVING COUNT(*) = 2 

這第二種形式是一個比較容易推廣到任意數量的標籤。將所有標籤放在IN子句中,並更改HAVING子句以匹配標籤數量。