#sql #vba
Вопрос:
У меня есть таблица в Microsoft Access с несколькими повторяющимися записями, содержащими разные значения в определенном поле столбца. Из-за оригинального дизайна тип поля столбца представляет собой короткий текст, значения которого содержат все числа, за исключением выбора «Без номера», и в настоящее время не могут быть изменены.
В VBA я пытаюсь найти запись, содержащую наибольшее значение в поле 3. Например, таблица может выглядеть следующим образом:
Field1 | Field2 | Field3 Jay Red 2 Aden Blue 1 Jay Red 5 Colin Orange 3 Jay Red No Number
Я хотел бы вернуть набор записей, содержащий строку, содержащую Jay, Red, 5.
Я написал строку SQL, но, насколько мне известно, это неправильно, потому что Access жалуется на следующее:
Вот как выглядит строка SQL:
mySQL = "SELECT " amp; _ "(SELECT TOP 1 Field3" amp; _ "FROM MyTable" amp; _ "Where Field1 = '" amp; rs1.Fields("Field1") amp; "'" amp; _ ") as Field3, Field1, Field2 " amp; _ "FROM " amp; _ "(SELECT Max(Val(Field3)) As Fld3, Field1, Field2 " amp; _ "FROM MyTable" amp; _ "GROUP BY Field3, Field1, Field2)" criteria = "Field1= '" amp; rs1.Fields("Field1") amp; "'" Set rs2 = CurrentDb.OpenRecordset(mySQL, _ dbOpenSnapshot, _ dbReadOnly) With rs2 rs2.FindLast criteria If Not rs2.NoMatch Then Dim str1 As String str1 = rs2.Fields("Field3") rs2.Close Set rs2 = Nothing End With
Я не думаю, что строка SQL в целом верна, но я также не уверен, как использовать функцию MAX в случае, когда поле столбца является строкой? Любая помощь будет признательна.
Ответ №1:
Вы можете добиться этого довольно просто с помощью SQL, который выглядит следующим образом:
SELECT TOP 1 Field1, Field2, Field3 FROM MyTable WHERE Field3 lt;gt; 'No Number' ORDER BY CInt(Field3) DESC;
Это предполагает, что единственным нечисловым значением является «Без числа».
Объединение TOP 1 с ORDER BY DESC дает тот же эффект получения максимального значения, но проще, потому что нет необходимости в дополнительном выборе. Если вам нужно добавить другие критерии, просто добавьте их «И» в предложение WHERE.
Редактировать
После вашего комментария о том, что вам, возможно, потребуется включить «Без номера», измените SQL на:
SELECT TOP 1 Field1, Field2, Field3 FROM MyTable WHERE -- your criteria here ORDER BY CInt(IIF(Field3='No Number',0,Field3)) DESC;
Я предполагаю здесь, что поле 3 всегда является числом больше 1, когда оно существует. Если оно может быть равно 0, то установите по умолчанию в IIF отрицательное число.
Комментарии:
1. спасибо, но мне нужно, чтобы набор записей был найден на основе
WHERE
условияField1
в первомrs1
наборе записей, а не условияField3
. Меняет ли это логику вашего кода? ОБНОВЛЕНИЕ: не видел вашего нижнего описания. Я проверю со своей стороны. Спасибо!2. Отлично работает, но остается один вопрос. Я добавил еще один критерий в предложение WHERE для поиска записи на
rs2
основе значения поляrs1
. Как я все еще могу сохранить найденную запись,rs2
если она содержит только «Без числа» в качестве значенияField3
?3. Пожалуйста, посмотрите мою правку
4. Я просто подумал о крайнем случае, и мне было интересно, так
Field3
как этоShort Text
тип, т. Е. aString
, я хочу изменить аргумент внутриIIF
, чтобы бытьIIF(Field3='No Number','No Number',Field3)
, поэтому, еслиField3='No Number'
, затем установите его какNo Number
вместо 0, в противном случае установите егоField3
равным . Тем не менее, я получаю aData type mismatch in criteria expression
из-за преобразования aString
в anInt
изCInt
функции. Я удалилCInt
, но если значениеField3
gt; 10, то gt;SELECT
не захватывает эту запись и захватывает что-либо нижеField3 = 10
. Как я могу этого достичь?5. Вы должны оставить IIF в том виде, в каком я его дал. Причина в том, что мы хотим включить его в порядок по, и для этого нам нужно преобразовать его в целое число. Ваша версия вообще не меняется — это то же самое, что просто поле!