Mysql 使用SQL查询生成多个最大值和最小值

Mysql 使用SQL查询生成多个最大值和最小值,mysql,sql,ms-access-2007,Mysql,Sql,Ms Access 2007,我对SQL的一个奇怪的限制感到沮丧——它显然无法在聚合函数之外将一条记录与另一条记录关联起来。我的问题总结如下。 我有一张桌子,已经整理好了。我需要找到它的最大值(注意复数!)和最小值。不,我不是在寻找单个最大值或单个最小值。更具体地说,我试图生成一个数字序列的局部峰值列表。生成该值的算法的粗略描述如下: WHILE NOT END_OF_TABLE IF RECORD != FIRST_RECORD AND RECORD != LAST_RECORD THEN IF ((RECORD(F

我对SQL的一个奇怪的限制感到沮丧——它显然无法在聚合函数之外将一条记录与另一条记录关联起来。我的问题总结如下。 我有一张桌子,已经整理好了。我需要找到它的最大值(注意复数!)和最小值。不,我不是在寻找单个最大值或单个最小值。更具体地说,我试图生成一个数字序列的局部峰值列表。生成该值的算法的粗略描述如下:

WHILE NOT END_OF_TABLE
 IF RECORD != FIRST_RECORD AND RECORD != LAST_RECORD THEN
  IF ((RECORD(Field)<RECORD_PREVIOUS(Field) AND RECORD(Field)<RECORD_NEXT(Field)) OR
      RECORD(Field)>RECORD_PREVIOUS(Field) AND RECORD(Field)>RECORD_NEXT(Field)) THEN
     ADD_RESULT RECORD
  END IF
 END IF
END WHILE
而不是\u表的\u结尾
如果记录!=第一次录制和录制!=最后一张唱片
如果((记录(字段)记录下一个(字段)),则
添加结果记录
如果结束
如果结束
结束时

看到问题了吗?我需要做一个查询,一条给定的记录必须与上一条记录和下一条记录的值进行比较。这甚至可以用标准SQL来完成吗?

许多人都有同样的沮丧情绪;虽然SQL非常适合处理常规集,但在处理特定于有序集的问题时,它却非常不足(表中的物理顺序或隐式或显式逻辑顺序都无关紧要)。有一些方法可以帮助您(例如,
rank()
row_number()
函数),但解决方案可能因RDBMS而异


如果您可以具体说明您使用的是哪个平台,我或其他人可以提供更详细的答案。

许多人都有同样的不满情绪;虽然SQL非常适合处理常规集合,但在处理特定于有序集合的问题时,它的缺陷是非常严重的(表中的物理顺序或隐式或显式逻辑顺序都无关紧要)。有一些方法可以帮助您(例如,
rank()
row_number()
函数),但解决方案可能因RDBMS而异


如果您可以具体说明正在使用哪个平台,我或其他人可以提供更详细的答案。

是的。您需要一个自连接-但是如果没有数据库架构,很难具体说明解决方案

具体地说,我想知道你提到的“订购”的事情——但我假设有一个“ID”字段可以用于此

(哦,我使用的是老式的连接语法,因为我是恐龙)

选择*
从myTable main,
我以前的表格,
我的下一张桌子
其中previous.id=main.id-1
next.id=main.id+1
和previous.record>main.record
和next.record

(我想我已经在大于/小于子句中正确地解释了您的需求,但是根据口味进行了调整)。

是的。您需要一个自连接-但是如果没有数据库架构,很难具体说明解决方案

具体地说,我想知道你提到的“订购”的事情——但我假设有一个“ID”字段可以用于此

(哦,我使用的是老式的连接语法,因为我是恐龙)

选择*
从myTable main,
我以前的表格,
我的下一张桌子
其中previous.id=main.id-1
next.id=main.id+1
和previous.record>main.record
和next.record
(我想我已经在大于/小于条款中正确地解释了您的要求,但需要根据口味进行调整)。

SELECT
current.RowID,
当前值,
当
(
(当前值<合并(先前值,当前值+1))
和
(当前值<合并(后续值,当前值+1))
)
然后
“最低限度”
其他的
“马克西玛”
终止
从…起
myTable电流
左连接
我的上一张表
在previous.RowID=(从myTable中选择MAX(RowID),其中RowIDcurrent.RowID)
哪里
(
(当前值<合并(先前值,当前值+1))
和
(当前值<合并(后续值,当前值+1))
)
或
(
(current.Value>合并(previous.Value,current.Value-1))
和
(current.Value>COALESCE(后续的.Value,current.Value-1))
)
注意:逻辑是从您那里复制的,但不满足在一个或多个连续记录中相等的局部最大值/最小值

注意:我创建了一个虚构的RowID来按顺序加入记录,重要的是这些加入会得到“先前”和“后续”记录

注意:左连接和合并语句导致第一个值和最后一个值始终计为最大值或最小值。

SELECT
current.RowID,
当前值,
当
(
(当前值<合并(先前值,当前值+1))
和
(当前值<合并(后续值,当前值+1))
)
然后
“最低限度”
其他的
“马克西玛”
终止
从…起
myTable电流
左连接
我的上一张表
在previous.RowID=(从myTable中选择MAX(RowID),其中RowIDcurrent.RowID)
哪里
(
(当前值<合并(先前值,当前值+1))
和
(当前值<合并(后续值,当前值+1))
)
或
(
(current.Value>合并(previous.Value,current.Value-1))
和
(current.Value>COALESCE(后续的.Value,current.Value-1))
)
注意:逻辑是从您那里复制的,但不满足在一个或多个连续记录中相等的局部最大值/最小值

注意:我创建了一个虚构的RowID来按顺序加入记录,重要的是这些加入会得到“先前”和“后续”记录

注意:左连接和合并语句导致
select *
from   myTable   main,
       myTable   previous,
       myTable   next
where  previous.id  = main.id - 1
and    next.id      = main.id + 1
and    previous.record > main.record
and    next.record     < main.record
SELECT
  current.RowID,
  current.Value,
  CASE WHEN
    (
     (current.Value < COALESCE(previous.Value,   current.Value + 1))
     AND
     (current.Value < COALESCE(subsequent.Value, current.Value + 1))
    )
  THEN
    'Minima'
  ELSE
    'Maxima'
  END
FROM
  myTable  current
LEFT JOIN
  myTable  previous
    ON previous.RowID = (SELECT MAX(RowID) FROM myTable WHERE RowID < current.ROWID)
LEFT JOIN
  myTable  subsequent
    ON subsequent.RowID = (SELECT MIN(RowID) FROM myTable WHERE RowID > current.ROWID)
WHERE
  (
   (current.Value < COALESCE(previous.Value,   current.Value + 1))
   AND
   (current.Value < COALESCE(subsequent.Value, current.Value + 1))
  )
  OR
  (
   (current.Value > COALESCE(previous.Value,   current.Value - 1))
   AND
   (current.Value > COALESCE(subsequent.Value, current.Value - 1))
  )
WITH ordered AS (
    SELECT ROW_NUMBER() OVER (ORDER BY your_sort_order) AS RowNumber
           ,* -- other columns here
)
SELECT *
FROM ordered
LEFT JOIN ordered AS prev
    ON prev.RowNumber = ordered.RowNumber - 1
LEFT JOIN ordered AS next
    ON next.RowNumber = ordered.RowNumber + 1
WHERE -- here you put in your local min/local max and end-point handling logic - end points will have NULL in next/prev