我有一系列搜索词。
$unprocessed=array("language1 word1", "language1 word2", "language1 word3");
$ unprocessed中的每个单词在名为“language1”的列中都有唯一的条目
如果找到,则返回行列“language2”,否则返回false。重要的是,如果找不到单词,则返回false。
1. $unprocessed=array("language1 word1", "language1 word2", "language1 word3");
2. MySQL Query (what is best way?)
3. $processed=array(false,"language2 word2","language2 word3");
是否可以在不循环查询的情况下执行此操作? 什么是最好的方法:使用WHERE =“word”,IN(“word”),LIKE =“word”或其他什么?
答案 0 :(得分:1)
$ unprocessed中的每个单词在名为" language1"
的列中都有一个唯一条目
这意味着你不想要使用LIKE。您可以运行这样的单个查询,并返回一个包含所请求单词的列的单个元组:
SELECT MAX(IF(language1=':word1', 1, 0)) AS hasWord1,
MAX(IF(language1=':word2', 1, 0)) AS hasWord2,
MAX(IF(language1=':word3', 1, 0)) AS hasWord3
FROM table WHERE language1 IN (':word1',':word2',':word3');
这比三个单字查询更具性能,特别是如果您在language1
上有索引。如果您需要语言表中的更多列(即不仅仅是单词,而且,例如,它的权重或其SVO状态或......),您最好为每个单词要求一个元组。但是在这种情况下,缺少单词将不会被返回(无论如何,你没有数据)。明智地使用LEFT JOIN加上第一个查询可以用来避免这种情况。
SELECT * FROM table WHERE language1 IN (':word1',':word2',':word3');
或 SELECT table2。* FROM表LEFT JOIN表AS table2 USING(primaryKey) WHERE table.language1 IN(':word1',':word2',':word3');
您还可以使用二进制表示来获取一列以识别单词:
SELECT MAX(IF(language1=':word1', 1, 0))
+ MAX(IF(language1=':word2', 2, 0))
+ MAX(IF(language1=':word3', 4, 0))
AS wordMask, ...
或者,在JOIN的情况下,它足以获得索引:
SELECT MAX(IF(language1=':word1', 1, 0)
+ MAX(IF(language1=':word2', 2, 0)
+ MAX(IF(language1=':word3', 3, 0)
AS wordIndex, ...
要构建查询,可以使用PHP foreach
循环。
如果是简单的翻译表:
SELECT MAX(IF(language1=':word1', language2, ':word1')) AS word1,
MAX(IF(language1=':word2', language2, ':word2')) AS word2,
MAX(IF(language1=':word3', language2, ':word3')) AS word3,
FROM table WHERE language1 IN (':word1',':word2',':word3');
将返回单词 n ,其中包含原始单词或"翻译的"来自language2专栏的词:
select MAX(IF(language1='computer', language2, '-')) AS hasWord1, MAX(IF(language1='ouijamaflip', language2, '-')) AS hasWord2 FROM tbl WHERE language1 IN ('computer', 'ouijmaflip');
+------------+----------+
| hasWord1 | hasWord2 |
+------------+----------+
| ordinateur | - |
+------------+----------+
您还可以使用语言优先级,再次在PHP中构建:
SELECT
MAX(IF (language1=':word1',
COALESCE(language2, language3, language4, ':default1')))
AS word1,
您可以将$default
设置为$word
,或者"?{$word}?"
或类似。
$words = array( 'computer', 'bytes', 'processor' /*, 'other'... */);
$langs = array( 'language2', 'language3' /*, 'language4', ... */ );
$rets = array();
$whrs = array();
$defs = array();
foreach ($words as $ndx => $word) {
$rets[] = "COALESCE(IF (language1 = ':word{$ndx}', COALESCE("
. implode(", ", $langs) . "), ':default{$ndx}')) AS word{$ndx}";
$whrs[] = "':word{$ndx}'";
$defs[] = "MISSING_{$word}";
}
$SQL = "SELECT "
. implode(", ", $rets) // All IFs
. " FROM table WHERE language1 IN("
. implode(", ", $whrs) . ");"; // All WHEREs
这将返回一个查询,例如:
SELECT
COALESCE(
IF (language1='computer',
COALESCE(language2, language3),
'MISSING_computer')
) AS word1,
COALESCE(
IF(language1='bytes',
COALESCE(language2, language3),
'MISSING_bytes')
) AS word2,
COALESCE(
IF(language1='processor',
COALESCE(language2, language3),
'MISSING_processor')
) AS word3
FROM tbl
WHERE language1 IN ('computer', 'bytes', 'processor');
最后,用这个tbl:
+-----------+------------+-----------+
| language1 | language2 | language3 |
+-----------+------------+-----------+
| computer | ordinateur | NULL |
| bytes | NULL | ottetti |
+-----------+------------+-----------+
它会返回
+------------+---------+-------------------+
| word1 | word2 | word3 |
+------------+---------+-------------------+
| ordinateur | ottetti | MISSING_processor |
+------------+---------+-------------------+
ordinateur 将取自第一语言,因为它在那里, ottetti 来自第二语言,因为第一语言是NULL,而处理器返回错误,因为它完全丢失或所有相关列都为NULL。您可以通过添加" language1"来区分这些情况。 (或诸如“EMPTY ROW'”之类的字符串)作为最不重要的语言。
答案 1 :(得分:0)
据我所知,根据评论你不能只用MySQL来做,你需要PHP来处理它。
假设你正在使用pdo ..这个伪代码应该为你做
function whatever($unprocessed){
global $db;
$processed = array();
foreach($unprocessed as $u){
$q = $db->prepare("SELECT * FROM language1 WHERE word = :wrd");
$q->execute(array(":wrd"=>$u));
$processed[] = $q->rowCount() ? $q->fetchColumn() : false;
}
return $processed;
}