Рассмотрите возможность перефакторинга вашего SQL процесса. Вместо объединения воедино динамических c SQL компонентов на прикладном уровне (т. Е. PHP), которые могут повлиять на удобочитаемость и удобство обслуживания, рассмотрим несколько самостоятельных объединений во временную таблицу из терминов со следующим определением:
CREATE TABLE tmp_terms (
id IDENTITY(1,1) NOT NULL,
term VARCHAR(255),
thesauraus_indicator BIT
)
В частности, выполнить агрегированный запрос по объединенным совпадениям, где MIN
возвращает 0 или 1. При таком подходе запрос такой же SQL поддерживается, но базовые условия , заполненные PHP, будут компонентом Dynami c.
Ниже приведена часть, не являющаяся тезаурусом предыдущей CASE
logi c. Кроме того, поскольку CONTAINS
не может использовать другой столбец, а только литеральное значение, в выражениях JOIN
используется LIKE
с начальным и конечным подстановочными знаками.
SELECT
i.id, i.thumbnail, i.description, i.brand, i.vendor,
MIN(case
when exact_desc.term IS NOT NULL
then 1
else 0
end) AS exact_description_match,
MIN(case
when market_match.term IS NOT NULL
then 1
else 0
end) AS market_match,
MIN(case
when desc_match.term IS NOT NULL
then 1
else 0
end) AS desc_match,
MIN(case
when vendor_match.term IS NOT NULL
then 1
else 0
end) AS vendor_match
FROM Martin.dbo.item_search i
LEFT JOIN tmp_terms exact_desc
ON i.description LIKE CONCAT(exact_desc.term, ' %')
AND exact_desc.thesaurus_indicator = 0
LEFT JOIN tmp_terms market_match
ON i.marketingDescription LIKE CONCAT('%', market_match.term, '%')
AND market_match.thesaurus_indicator = 0
LEFT JOIN tmp_terms desc_match
ON i.description LIKE CONCAT('%', desc_match.term, '%')
AND desc_match.thesaurus_indicator = 0
LEFT JOIN tmp_terms vendor_match
ON i.vendor LIKE CONCAT('%', vendor_match.term, '%')
AND vendor_match.thesaurus_indicator = 0
GROUP BY i.id, i.thumbnail, i.description, i.brand, i.vendor
Для интеграции тезауруса сопоставьте, используйте UNION
в CTE или подзапросе перед агрегированием во внешнем запросе.
WITH sub AS
(SELECT
i.id, i.thumbnail, i.description, i.brand, i.vendor,
exact_desc.term AS exact_desc_term, market_match.term AS market_match_term,
desc_match.term AS desc_match_term, vendor_match.term AS vendor_match_term
FROM Martin.dbo.item_search i
LEFT JOIN tmp_terms exact_desc
ON i.description LIKE CONCAT(exact_desc.term, ' %')
AND exact_desc.thesaurus_indicator = 0
LEFT JOIN tmp_terms market_match
ON i.marketingDescription LIKE CONCAT('%', market_match.term, '%')
AND market_match.thesaurus_indicator = 0
LEFT JOIN tmp_terms desc_match
ON i.description LIKE CONCAT('%', desc_match.term, '%')
AND desc_match.thesaurus_indicator = 0
LEFT JOIN tmp_terms vendor_match
ON i.vendor LIKE CONCAT('%', vendor_match.term, '%')
AND vendor_match.thesaurus_indicator = 0
UNION
SELECT
i.id, i.thumbnail, i.description, i.brand, i.vendor,
th_exact_desc.term, th_market_match.term,
th_desc_match.term, th_vendor_match.term
LEFT JOIN tmp_terms th_exact_desc
ON i.description LIKE CONCAT(th_exact_desc.term, ' %')
AND th_exact_match.thesaurus_indicator = 1
LEFT JOIN tmp_terms th_market_match
ON i.marketingDescription LIKE CONCAT('%', th_market_match.term, '%')
AND th_market_match.thesaurus_indicator = 1
LEFT JOIN tmp_terms th_desc_match
ON i.description LIKE CONCAT('%', th_desc_match.term, '%')
AND th_desc_match.thesaurus_indicator = 1
LEFT JOIN tmp_terms th_vendor_match
ON i.vendor LIKE CONCAT('%', th_vendor_match.term, '%')
AND th_vendor_match.thesaurus_indicator = 1
)
SELECT sub.id, sub.thumbnail, sub.description, sub.brand, sub.vendor,
MIN(case
when sub.exact_desc_term IS NOT NULL
then 1
else 0
end) AS exact_description_match,
MIN(case
when sub.market_match_term IS NOT NULL
then 1
else 0
end) AS market_match,
MIN(case
when sub.desc_match_term IS NOT NULL
then 1
else 0
end) AS desc_match,
MIN(case
when sub.vendor_match_term IS NOT NULL
then 1
else 0
end) AS vendor_match
FROM sub
GROUP BY sub.id, sub.thumbnail, sub.description, sub.brand, sub.vendor
Примечание. Приведенные выше запросы могут нуждаться в корректировке в соответствии с потребностями конечного использования и тестированием. Эффективность может варьироваться в зависимости от количества поисковых запросов. Но, в конечном счете, концепция заключается в том, чтобы взаимодействовать с данными в наборах, а не долго объединять CASE WHEN...
logi c, которые растут с поисковыми терминами.
Наконец, в PHP просто очистите и заполните временная таблица с новыми значениями с использованием параметризации и запуска любого из указанных выше окончательных запросов:
odbc_exec($connection, "DELETE FROM tmp_terms");
$stmt = odbc_prepare($connection,
"INSERT INTO tmp_terms (term, thesaurus_indicator)
VALUES (?, ?)");
// NON-THESAURUS TERMS
foreach($search_terms as $t) {
odbc_execute($stmt, array($t, 0));
}
// THESAURUS TERMS
foreach($th_search_terms as $t) {
odbc_execute($stmt, array($t, 1));
}
// RUN FINAL SELECT QUERY
$result = odbc_exec($connection, "my_final_above_query");
while(odbc_fetch_row($result)){
for($i=1; $i<=odbc_num_fields($result); $i++){
// ... odbc_result($result,$i);
}
}