MS доступ к сложному запросу. запрос двух последних записей по дате для каждого идентификатора. очень медленно - PullRequest
0 голосов
/ 13 октября 2009

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

ВЫБРАТЬ Widgets.WidgetID, Widgets.Color, Widgets.Size, T.Date, T.Param1, T.Param2, *
ИЗ ТЕСТОВ В КАЧЕСТВЕ ВНУТРЕННЕГО СОЕДИНЕНИЯ Виджеты ВКЛ T.WidgetID = Widgets.WidgetID
ГДЕ (((Выберите СЧЕТ (*) ИЗ ТЕСТОВ
ГДЕ WidgetID = T.WidgetID AND Date> T.Date)) <2); </p>

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

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

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

Выберите Widgets.WidgetID, Widgets.Color, Widgets.Size, Widgets.Type
Из виджетов
WHERE (getColorFlag () = True AND (Widgets.Color) In (выберите цвет из списка цветов))
ИЛИ (getSizeFlag () = True AND (Widgets.Size) In (Выбрать размер из SizeList))
ИЛИ (getTypeFlag () = True AND (Widgets.Type) In (Выбрать тип из списка типов))

Ответы [ 3 ]

1 голос
/ 13 октября 2009

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

0 голосов
/ 01 июня 2012

Просто, правда.

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
0 голосов
/ 13 октября 2009

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

Функция createWidgetFilterTemp ()
Dim mySQL
Dim deleteSQL
deleteSQL = "DELETE * FROM TempWidgetFilter"
mySQL = "SELECT * INTO TempWidgetFilter ОТ WidgetFilter" DoCmd.SetWarnings False
DoCmd.RunSQL deleteSQL
DoCmd.RunSQL mySQL
DoCmd.SetWarnings True
Конечная функция

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

Функция createWidgetTemp ()
Dim mySQL
Dim deleteSQL
deleteSQL = "DELETE * FROM TempWidgetCombo"
mySQL = "SELECT * INTO TempWidgetCombo FROM WidgetCombo" DoCmd.SetWarnings False
DoCmd.RunSQL deleteSQL
DoCmd.RunSQL mySQL
DoCmd.SetWarnings True
Конечная функция

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

...