ACCESS 2007: определить максимальное значение для строки в нескольких столбцах - PullRequest
0 голосов
/ 27 октября 2009

У меня есть таблица с несколькими столбцами даты на сотрудника:

   Emp 1, Date1, Date2, Date3
   Emp 2, Date1, Date2, Date3

и т.д.

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


Спасибо за оперативные ответы! Есть ли способ сделать это без использования оператора iif? Я хотел бы обобщить это, если это вообще возможно, так как есть несколько других полей даты, и это становится действительно громоздким, чтобы выяснить логику IIF.

Кроме того, я забыл упомянуть, что любая из этих дат может быть пустой, и логика IIF, похоже, возвращает NULL в качестве максимального значения.

Ответы [ 5 ]

1 голос
/ 27 октября 2009
SELECT ID, Max(TheDate) AS MaxDate
FROM
(
   SELECT ID, Date1 AS TheDate
   FROM myTable
   UNION 
   SELECT ID, Date2 AS TheDate
   FROM myTable
   UNION
   SELECT ID, Date3 AS TheDate
   FROM myTable
)
GROUP BY ID

Я знаю, что это не чистое решение.
Но это то, что вы ищете, когда писали о UNION.

РЕДАКТИРОВАТЬ: Вы можете использовать UNION ALL вместо UNION. С вышеупомянутым запросом, это не будет иметь значения в выводе, я полагаю.

0 голосов
/ 13 июня 2016

Вау! Я вижу, что это слишком сложно сделать простым: Max(Field-Constant1,Constant2).

Моя цель: вычислить значение, зависящее только от одного поля, но не допускать, чтобы вычисленное значение было меньше константы.

Пример строк в таблице из двух полей (KeyField, ValueField):

1 10
2 5
3 8
4 Null

Я хочу выбрать, который возвращает (когда Constant1 = 6 и Constant2 = 1), я поставил все математические вычисления, чтобы прояснить это (только самая верхняя правая часть после последнего = это то, что я хочу):

1 Max(10-6,1)=Max(4,1)=4
2 Max(5-6,1)=Max(-1,1)=1
3 Max(8-6,1)=Max(2,1)=1
4 Max(Null-6,1)=Max(Null,1)=Null

Так что я просто хочу (когда Constant1 = 6 и Constant2 = 1) на случай, если недостаточно ясно:

1 4
2 1
3 1
4 Null

Остерегайтесь этого Нуль.

Я действительно хочу что-то действительно более сложное, но решив, что я смогу решить сложный, который я хочу.

Это может быть возобновлено как: -Return Null, если значение равно Null или не является допустимым значением для используемого математического оператора (не всегда это просто - или +, и т. Д.) -Возвратите вычисленное значение, если возможно выполнить математику, но ограничено диапазоном (не меньше значения и не больше другого значения).

Если я сделаю это на псевдокоде, это будет выглядеть так:

try // try to do the maths
   MyCalculatedValue=SomeMaths(FieldValue);
   MyCalculatedValue=Min(Max(MyCalculatedValue,MinValue),MaxValue);
except // In case the SomeMaths can not be done (FieldValue is Null, negative square, division by zero, etc)
      MyCalculatedValue=Null;
end;
return MyCalculatedValue;

На всякий случай, если кто-то скажет, что база данных не нормализована: я хочу выполнить некоторые математические операции с полем, а затем ограничить результат диапазоном; таким образом, самая маленькая примерная база данных будет иметь только одну таблицу, которая будет иметь только два поля (поле уникального ключа, поле данных), которое невозможно полностью нормализовать; я не говорю о maximun некоторых полей в строке, ни maximun для полной таблицы в поле (агрегатные функции), просто я просто хочу установить нижний и верхний пределы для вычисляемого значения, но рассматриваю Null, когда такое значение Нуль, или математические вычисления, которые должны быть выполнены с таким значением, не могут быть выполнены (такие случаи, как Constant1 / (FieldValue-Constant2) и т. д.).

Реальный образец на тот случай, если кто-то не получит, когда это можно использовать:

Поля таблицы:

ID (Key)
SpacePosition (DecimalData)

Желаемые поля результатов для запроса:

ID as ID
Min(Max(SpacePosition-SomeSpaceLongitud,StartPosition),EndPosition) AS RangeStart
Min(Max(SpacePosition+SomeSpaceLongitud,StartPosition),EndPosition) AS RangeEnd

Надеюсь, что образец ясен, и надеюсь, что кто-то может помочь, с чем-то более простым, чем использование функций VBA!

П.Д .: Подумайте, что такие математические вычисления более сложны, чем просто + и -, и таблица содержит намного больше регистров, чем несколько, подумайте о нескольких миллиардах регистров. P.P .: Не стоит жестко кодировать такие результаты, поскольку это не будет нормализованная база данных и, что хуже всего, такие пределы диапазона являются значениями, вводимыми пользователем при выполнении запроса.

0 голосов
/ 27 октября 2009

Если вы не хотите ограничивать решение SQL, вы можете использовать функцию iMax ():

  Public Function iMax(ParamArray p()) As Variant
  ' Idea from Trevor Best in Usenet MessageID rib5dv45ko62adf2v0d1cot4kiu5t8mbdp@4ax.com
    Dim i As Long
    Dim lngUBound As Long
    Dim v As Variant

    v = p(LBound(p))
    lngUBound = UBound(p)
    For i = LBound(p) + 1 To lngUBound
      If v < p(i) Then
         v = p(i)
      End If
    Next
    iMax = v
  End Function

Я называю это "Immediate Max ()" по аналогии с IIf (), Immediate If (), потому что он предназначен для обработки на уровне строк в запросе.

0 голосов
/ 27 октября 2009

Будет ли что-то подобное работать?

select
  EmployeeColumn,
  iff(iif(Date1 > Date2, Date1, Date2) > Date3, iif(Date1 > Date2, Date1, Date2), Date3)
from yourTable
0 голосов
/ 27 октября 2009

Хотелось бы что-то вроде этого сделать: (это был MSSQL2008, не уверенный, будет ли он работать в Acess)

Создание тестовых данных

create table t1
    ( EmployeeId int,
      Date1  datetime,
      Date2  datetime,
      date3  datetime)

insert into t1 values (1, '2009-10-11', '2009-04-01', '2009-12-25')
insert into t1 values (2, '2009-10-24', '2009-04-03', '2009-12-19')

Мой запрос

select case 
    when date1 > date2 and DATE1 > date3 then date1
    when date2 > date1 and date2 > date3 then date2
    when date3 > date1 and date3 > date2 then date3
    end as highest
    from t1 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...