2012-06-14 3 views
2

Я создал функцию VBA в Access 2010, чтобы сравнить список терминов в одной таблице со списком терминов в другой таблице. Если значения одинаковы (не обязательно точное совпадение), я суммирую значение из столбца из второй таблицы для каждого совпадения. TableA имеет приблизительно 150 терминов. TableB имеет приблизительно 50 000 терминов со связанным числом (целое число).Как я могу эффективно сравнивать строковые значения из двух таблиц в Access?

Пример таблица:

TableA    TableB 
---------   ---------- 
ID     ID 
Term    Term 
        Count 

У меня есть простой SQL запрос, который вызывает функцию VBA для сравнения терминов и просуммировать количество, если они имеют нечеткий матч.

SQL:

SELECT TableA.[Term], TermCheck(TableA.[Term]) AS [Term Count] FROM TableA ORDER BY 2 DESC; 

VBA:

Option Compare Database 

Public Function TermCheck(Term) As Long 

    Dim rst As DAO.Recordset 
    Set rst = CurrentDb.OpenRecordset("TableB", dbOpenDynaset) 
    Dim ttl As Long 
    ttl = 0 

    With rst 
     While Not .EOF 
      If rst(1) Like "*" & Term & "*" Then 
       ttl = ttl + rst(2) 
      End If 
      .MoveNext 
     Wend 
    End With 

    rst.Close 
    Set rst = Nothing 

    CurrentDb.Close 

    TermCheck = ttl 

End Function 

Проблема у меня есть то, что он использует около 50% моего процессора, и я хотел бы сделать это как можно более. Есть ли более эффективный способ выполнить эту задачу с помощью Access? Переход к чисто SQL-альтернативе на данный момент не является вариантом, хотя это сделает меня счастливее. Я не гуру доступа или VBA, но чувствую, что в своем запросе мне не хватает чего-то очевидного, что улучшит производительность.

EDIT:

Ожидаемый результат можно было бы перечислить все слагаемые в TableA с суммой столбца счета от TableB где произошло нечеткое соответствие.

Пример данных: Результат

TableA 
------------- 
1 blah 
2 foo 
3 bar 
4 zooba 

TableB 
------------- 
1 blah 16 
2 blah2 9 
3 foo  7 
4 food 3 
5 bar  3 

Пример:

Term   Count 
--------------------- 
blah   25 
foo   10 
bar   3 
zooba   0 
+0

Я не могу переместить его в SQL для целей доставки. В настоящее время у клиента нет доступной среды SQL для установки решения на базе SQL. – thisIsSteve

+0

Чтобы прояснить, по чисто SQL, я имел в виду что-то вроде SQL Server/MySQL/Oracle. – thisIsSteve

ответ

1
SELECT 
    TableA.Term, 
    Nz(subq.SumOfCount, 0) AS Count 
FROM 
    TableA 
    LEFT JOIN 
    (
     SELECT a.Term, Sum(b.Count) AS SumOfCount 
     FROM TableA AS a, TableB AS b 
     WHERE b.Term ALike '%' & a.Term & '%' 
     GROUP BY a.Term 
    ) AS subq 
    ON TableA.Term = subq.Term; 

Edit: Я использовал ALike и стандартный ANSI характер дикой карты. Это позволяет корректно запускать запрос независимо от того, выполняется ли он из режима SQL-89 или SQL-92. Если вы предпочитаете * джокер, используйте эту версию статьи WHERE:

WHERE b.Term Like '*' & a.Term & '*' 

Обратите внимание, что только делать сращивание правильно при запуске из режима SQL-89.

+0

Ничего себе, я думаю, я передумал мой первоначальный план. Это просто и эффективно. Спасибо @HansUp! – thisIsSteve

+0

Я попытался отредактировать, чтобы переключить% на *, чтобы быть более специфичным для доступа, но недостаточно символов для изменения. – thisIsSteve

+0

Это прекрасно. Благодаря! – thisIsSteve

1

На этих линиях?

SELECT ta.ID, tb.Term, ta.Term, tb.Count 
FROM ta, tb 
WHERE ta.Term Like "*" & tb.term & "*"; 

ID tb.Term ta.Term Count 
2 hat  hat  2 
3 hat  the hat 2 
3 the hat the hat 4 
4 mat  mat  6 
5 mat  matter 6 
5 matter matter 8 
+0

Хотя это значительно более эффективно, оно не совсем подходит к результату, который я ищу. Я отредактирую свой вопрос, чтобы уточнить ожидаемые результаты немного больше. – thisIsSteve

0

Я обычно построить выражение с помощью IIF:

TestFlag:iif([TableA]![Term] = [TableB]![Term],"Same","Different") 
Смежные вопросы