Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 查找多列上的最大值_Sql_Oracle11g - Fatal编程技术网

Sql 查找多列上的最大值

Sql 查找多列上的最大值,sql,oracle11g,Sql,Oracle11g,我试图查询最近一学期的会议列表,其中学期由两个字段(年份、学期)确定。下面是该模式的基本概要: Otherfields Year Semester meeting1 2014 1 meeting2 2014 1 meeting3 2013 2 ... etc ... 由于应先考虑本年度的最大值,然后再考虑本学期的最大值,因此我的结果应如下所示: Otherfields Year Semester meeting1

我试图查询最近一学期的会议列表,其中学期由两个字段(年份、学期)确定。下面是该模式的基本概要:

Otherfields    Year    Semester
meeting1       2014    1
meeting2       2014    1
meeting3       2013    2
... etc ...
由于应先考虑本年度的最大值,然后再考虑本学期的最大值,因此我的结果应如下所示:

Otherfields    Year    Semester
meeting1       2014    1
meeting2       2014    1

不幸的是,在每一列上单独使用MAX()函数将试图找到Year=2014,term=2,这是不正确的。我尝试了两种使用嵌套子查询和内部联接的方法,但都没有成功。解决这个问题最直接的方法是什么?

如果有更有效的方法来解决这个问题(并避免重复的子查询),我不会感到惊讶,但这将得到您想要的答案:

SELECT * FROM table WHERE Year = 
    (SELECT MAX(Year) FROM table)
AND Semester =
    (SELECT MAX(Semester) FROM table WHERE Year =
        (SELECT MAX(Year) FROM table))

您为什么不直接使用“订购依据”

这样,它会更容易处理,也不会那么凌乱!!:)

编辑

如果您需要2014年的有限结果,请使用
Limit
子句(对于mysql)

它将
先下单
,然后得到限制-10,这样你就得到了你的有限结果集

这将获取如下输出:

Otherfields    Year    Semester
meeting1       2014    1
meeting2       2014    1
meeting1       2013    1
meeting2       2013    2

使用窗口功能:

SELECT Year, Semester, RANK() OVER(ORDER BY Year DESC, Semester DESC) R
FROM your_table;
R
将是一列,包含这对夫妇的“等级”(年份、学期)。然后可以将此列用作筛选器,例如:

WITH TT AS (
  SELECT Year, Semester, RANK() OVER(ORDER BY Year DESC, Semester DESC) R
  FROM your_table
)
SELECT ...
FROM TT
WHERE R = 1;
如果不希望列组之间存在间隙,可以使用
densite\u-rank
而不是
rank

这个答案假设您使用的RDBMS足够先进,可以提供窗口功能(即不是MySQL)

这里是Postgres:

with table2 as /*virtual temporary table*/
(
    select *, year::text || semester as yearsemester
    from table
)
select Otherfields, year, semester
from table2
where (Otherfields, yearsemester) in
(
    select Otherfields, max(yearsemester)
    from table2
    group by Otherfields
)

我想得太多了,有一个简单得多的方法:

SELECT Meeting.year, Meeting.semester, Meeting.otherFields
FROM Meeting
JOIN (SELECT year, semester
      FROM Meeting
      WHERE ROWNUM = 1
      ORDER BY year DESC, semester DESC) MostRecent
  ON MostRecent.year = Meeting.year
     AND MostRecent.semester = Meeting.semester
(及)

注意,这种变体应该适用于几乎alldbs(在子查询中支持限制子句的任何内容);以下是MySQL版本,例如:

SELECT Meeting.year, Meeting.semester, Meeting.otherFields
FROM Meeting
JOIN (SELECT year, semester
      FROM Meeting
      ORDER BY year DESC, semester DESC
      LIMIT 1) MostRecent
  ON MostRecent.year = Meeting.year
     AND MostRecent.semester = Meeting.semester
(……和)


考虑到一些数据,这对Oracle来说应该是有效的,我怀疑其他数据库也会如此(考虑到优化器可以采用的快捷方式)。在大多数没有提供分区子句(没有窗口)的情况下,这应该能够代替使用诸如
行号()之类的内容。

在这里回答我自己的问题:

这个查询是在一个存储过程中运行的,所以我在查询的其余部分之前,在单独的查询中找到了最大年/学期数。这很可能是低效和不雅的,但也是最容易理解的方法——我不需要担心我的团队中的其他成员会被它弄糊涂。我将把这个问题留在这里,因为它通常适用于许多其他情况,而且似乎有一些很好的答案提供了替代方法

-- Find the most recent year.
SELECT MAX(year) INTO max_year FROM meeting;

-- Find the most recent semester in the year.
SELECT MAX(semester) INTO max_semester FROM meeting WHERE year = max_year;

-- Open a ref cursor for meetings in most recent year/semester.
OPEN meeting_list FOR
    SELECT otherfields, year, semester
    FROM   meeting
    WHERE  year = max_year
    AND    semester = max_semester;

mysql
oracle
??就个人而言,我会创建一个年/学期表,本质上类似于常规日历表(或者作为一个表中的字段)。然后你只需将年/学期id放在这个表中。这确实需要一个额外的查询连接(年/学期可能是连续的这一事实是一个不应该依赖的实现细节),但应该是一个快速的连接。此外,还可以很容易地给出学期开始/结束日期等。这并不能消除上学期会议以外的行。我不明白你的意思……你能重新措辞吗?你的查询将返回表中的所有行,而原始海报只需要上学期的行。耶,我同意,这就是我后来添加,
where
子句的原因,另外,为了限制返回的行,OP可以使用
limit
,但他/她没有提到DB正在使用什么!!嗯,不。首先,你这学期的顺序是错误的。如果有10个以上的会议,会发生什么情况?是的-您可以修改双嵌套的会议以用作子查询表引用,并将其作为联接包含。虽然Oracle有更好的操作可用,但这将在其他数据库(如MySQL)中工作。对于没有更好手段的数据库,组合相关字段是一个可行的选择,尽管我会以不同的方式构造查询的其余部分。我猜这是在Oracle中运行此查询最有效的方法。出于好奇,RANK()函数是Oracle特有的,还是可以在不同的DBMS之间移植?(例如MSSQL、PostgreSQL)在任何具有窗口函数的DBMS中都应该有一个等价物,但我使用PostgreSQL编写了这个特定的查询。
SELECT Meeting.year, Meeting.semester, Meeting.otherFields
FROM Meeting
JOIN (SELECT year, semester
      FROM Meeting
      ORDER BY year DESC, semester DESC
      LIMIT 1) MostRecent
  ON MostRecent.year = Meeting.year
     AND MostRecent.semester = Meeting.semester
-- Find the most recent year.
SELECT MAX(year) INTO max_year FROM meeting;

-- Find the most recent semester in the year.
SELECT MAX(semester) INTO max_semester FROM meeting WHERE year = max_year;

-- Open a ref cursor for meetings in most recent year/semester.
OPEN meeting_list FOR
    SELECT otherfields, year, semester
    FROM   meeting
    WHERE  year = max_year
    AND    semester = max_semester;