2009-10-12 1 views
0

У меня есть две таблицы. Виджеты, в которых есть информация о каждом виджете (Цвет, размер и т. Д.); каждый виджет имеет уникальный идентификатор, WidgetID.
Другая таблица - это тесты, и в ней содержится информация о нескольких тестах, которые были запущены для каждого виджета. Следовательно, эта таблица имеет несколько строк для каждого WidgetID. Он содержит информацию, которую мы можем назвать (WidgetID, Date, Param1, Param2 и т. Д.); тестовая информация.
Я написал запрос, который находит для каждого WidgetID последние два теста по дате. SQL выглядит следующим образом:ms доступ к сложному запросу. запрос последних двух записей по дате для каждого идентификатора. очень медленно

ВЫБРАТЬ Widgets.WidgetID, Widgets.Color, Widgets.Size, T.Date, T.Param1, T.Param2 *
ОТ Tests AS T INNER JOIN Widgets ON T.WidgetID = Widgets.WidgetID
WHERE (((Выберите COUNT (*) FROM Тесты
ГДЕ WidgetID = T.WidgetID AND Date> T.Date)) < 2);

Это работает очень хорошо. Однако это дает мне слишком много виджетов. Я создал запрос, который фильтрует виджеты под названием WidgetFilter. Это в основном просто выбирает те, которые я хочу, основываясь на том, что я выбираю. Идея заключалась в том, что я бы выполнил тот же запрос, заменив «Виджеты» в коде выше с помощью «WidgetFilter». Однако, когда я это делаю, это происходит навсегда. На самом деле, он просто замерзает. Я оставил его на полтора часа, и он просто сидел там, и я должен был удалить ctl. Моя единственная мысль состоит в том, что он запрашивает запрос WidgetFilter для каждой строки тестов (и это много строк). Я также попытался применить критерии фильтра в исходном запросе. Я получаю тот же результат.

Есть ли лучший способ сделать это? Либо один запрос, который делает все это и, возможно, даже не выглядит так или что я думал, так это то, что должен быть способ запуска запроса WidgetFilter один раз и заставить эти данные обращаться к таблице как таковой (не существует такой вещи, как временная таблица). Таким образом, он не запускает WidgetFilter для каждого элемента в тестах.

EDIT:
WidgetFilter на самом деле довольно сложный. Я создал эти таблицы выбора GUI, где пользователь видит два столбца. Выбор слева и список, который он создает справа и посередине, - кнопка добавления и кнопка удаления. Затем они вызывают отчет, который выполняет WidgetFilter, yadda yadda yadda. В любом случае, когда пользователь добавляет элемент, он добавляет этот элемент в таблицу. Итак, для категории Widget, Color, появится таблица ColorList. Пользователь создает этот список через gui. Есть три из этих guis (Цвет, Размер, Тип). Для каждого из них есть таблица, и тогда существует глобальное логическое (например, ColorFlag), которое сообщает, какой фильтр использовать (цвет, размер или тип).
Так, в запросе WidgetFilter критерии боксировать под цвет будет иметь это:
В (Выбрать цвет От ColorList)
и есть выражение колонки Expr1: getColorFlag(), который представляет собой модуль, который возвращает значение из Глобальная переменная ColorFlag. и в то же время применяется таблица цветов. Итак, когда все сказано и сделано, есть три ряда критериев. Код выглядит следующим образом:

Выберите Widgets.WidgetID, Widgets.Color, Widgets.Size, Widgets.Type
От Виджеты
WHERE (getColorFlag() = True И (Widgets.Color) В (Выбрать цвет FROM ColorList))
ИЛИ (getSizeFlag() = True И (Widgets.Size) В (Выбрать размер от SizeList))
ИЛИ (getTypeFlag() = True И (Widgets.Type) В (Выберите тип ОТ TypeList))

ответ

0

Ok. Вот что я в итоге сделал. Я создал временную таблицу с помощью VBA кода, как это:

Функция createWidgetFilterTemp()
Dim MySql
Dim DeleteSQL
DeleteSQL = "DELETE * FROM TempWidgetFilter"
MYSQL = "SELECT * INTO TempWidgetFilter ИЗ WidgetFilter" DoCmd.SetWarnings Ложные
DoCmd.RunSQL DeleteSQL
DoCmd.RunSQL MySql
DoCmd.SetWarnings Правда
End Function

I Inner Загрузите TempWidgetFilter и тесты в запрос под названием WidgetCombo. Это дало мне доступ ко всей тестовой информации и всей информации о виджетах только для интересующих меня элементов WidgetID. Я попытался сделать тот же запрос с помощью оператора Select Count (*), но у меня возникла такая же проблема с тем, что Access замерзает , Итак, я тогда создал другую временную таблицу с помощью VBA, используя такой код:

Функция createWidgetTemp()
Dim MySql
Dim DeleteSQL
DeleteSQL = "DELETE * FROM TempWidgetCombo"
MYSQL = «SELECT * INTO TempWidgetCombo ИЗ WidgetCombo» DoCmd.SetWarnings Ложные
DoCmd.RunSQL DeleteSQL
DoCmd.RunSQL MySql
DoCmd.SetWarnings Правда
End Function

Я запускал обе эти функции всякий раз, когда я вызывал запросы из формы. Это сработало! На самом деле он работал довольно быстро. Я думаю, что это сработало бы без первой таблицы temp, но, поскольку это как временная таблица, а не просто запрос, другая часть моего приложения работает быстрее, поэтому я ее оставил. Кстати, мне пришлось запускать его один раз, когда строка удаления прокомментировалась так, чтобы она создавала таблицу. Я думаю, что я мог бы просто создать таблицу вручную, но таким образом он получил все поля там правильно. Спасибо за помощь, я надеюсь, что это поможет кому-то еще, кто придет в будущем, искать помощь по временному столу.

1

Одна вещь, о которой вы, возможно, не знаете.Я полагаю, что большинство версий Access (не знаю о 2007 году) уйдут на сухую землю, если у вас есть подвыбор, который возвращает значение NULL для любой строки. Итак, если в любой из этих таблиц есть NULL Color, Size или Type, которые могут вызвать симптомы, которые вы видите.

+0

Я проверил ... это было не так. нет нулевых значений. Спасибо хоть. – Matt

0

Простой, действительно.

SELECT TOP 2 Widgets.WidgetID, Widgets.Color, Widgets.Size, T.Date, T.Param1, T.Param2,* 
FROM Tests AS T INNER JOIN Widgets ON T.WidgetID=Widgets.WidgetID 
ORDER BY T.Date DESC 
Смежные вопросы