Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.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_Oracle_Group By_Sql Order By_Union - Fatal编程技术网

Sql 如何从有序查询中选择第一条和最后一条记录,而不使用并集、交集等

Sql 如何从有序查询中选择第一条和最后一条记录,而不使用并集、交集等,sql,oracle,group-by,sql-order-by,union,Sql,Oracle,Group By,Sql Order By,Union,所以,我承认这是我昨天的一项考试任务,但我没能应付。。。 我有一个简单的数据库,里面有人们的姓名、薪水和职能(A、B、C、D、E和F),我必须选择平均工资最高和最低的职能。我还必须忽略函数C。 数据库示例: name salary function Mike 100 A John 200 F Jenny 500 B Fred 400 B ...

所以,我承认这是我昨天的一项考试任务,但我没能应付。。。 我有一个简单的数据库,里面有人们的姓名、薪水和职能(A、B、C、D、E和F),我必须选择平均工资最高和最低的职能。我还必须忽略函数C。 数据库示例:

name      salary      function
Mike        100          A
John        200          F
Jenny       500          B
Fred        400          B
...         250          C
...         800          D
...         100          E
...         350          E
...         450          F
...         250          A
...         500          B
结果示例:

function          avg salary
  A                  300
  C                  600

我知道如何使用UNION来实现这一点,因为在oracle中,我可以按函数order by salary进行分组,并使用order by salary desc进行UNION,例如,在两个选择中仅获取1行。我可以使用WHERE,但不可能使用WHERE和聚合(比如AVG(salary)),但是如何在没有并集、减号或交集的单个查询中实现这一点?

您可以使用
rank
函数(使用
densite\u rank
如果平均值之间存在联系的话)按平均工资对行进行排序。然后选择排名最高和最低的行

select t1.function, avg(t1.salary)
from (select 
       rank() over(order by avg(salary) desc) rnk_high
      ,rank() over(order by avg(salary)) rnk_low
      ,function 
      from tablename
      group by function) t 
join tablename t1 on t.function = t1.function
where rnk_high = 1 or rnk_low = 1
group by t1.function

您可以使用
rank
函数(如果平均值之间存在联系,则使用
densite\u rank
)按平均工资对行进行排序。然后选择排名最高和最低的行

select t1.function, avg(t1.salary)
from (select 
       rank() over(order by avg(salary) desc) rnk_high
      ,rank() over(order by avg(salary)) rnk_low
      ,function 
      from tablename
      group by function) t 
join tablename t1 on t.function = t1.function
where rnk_high = 1 or rnk_low = 1
group by t1.function

您可以在Oracle中使用子查询吗? 试试这个

Select z.Function from 
   (Select Function, Avg(Salary) avgSal
    from tableName
    group By function) z
Where z.avgSal = (Select Max(z0.avgSal) 
                  from (Select Avg(Salary) avgSal
                        from tableName
                        group By function) z0)
  Or z.avgSal = (Select Min(z1.avgSal) 
                  from (Select Avg(Salary) avgSal
                        from tableName
                        group By function) z1)

您可以在Oracle中使用子查询吗? 试试这个

Select z.Function from 
   (Select Function, Avg(Salary) avgSal
    from tableName
    group By function) z
Where z.avgSal = (Select Max(z0.avgSal) 
                  from (Select Avg(Salary) avgSal
                        from tableName
                        group By function) z0)
  Or z.avgSal = (Select Min(z1.avgSal) 
                  from (Select Avg(Salary) avgSal
                        from tableName
                        group By function) z1)

与@vkp的方法类似,但没有连接回基表:

select function, avg_salary
from (
  select function, avg(salary) as avg_salary,
    rank() over (order by avg(salary)) as rnk_asc,
    rank() over (order by avg(salary) desc) as rnk_desc
  from tablename
  group by function
)
where rnk_asc = 1 or rnk_desc = 1;

F AVG_SALARY
- ----------
D        800
A        175
两个
rank()
调用将每个函数/平均值按顺序排列:

select function, avg(salary) as avg_salary,
  rank() over (order by avg(salary)) as rnk_asc,
  rank() over (order by avg(salary) desc) as rnk_desc
from tablename
group by function;

F AVG_SALARY    RNK_ASC   RNK_DESC
- ---------- ---------- ----------
D        800          6          1
B    4.7E+02          5          2
F        325          4          3
C        250          3          4
E        225          2          5
A        175          1          6
形成内联视图;然后,外部查询只选择在生成的列中排名1的行,这里是D和A


如果你有两个平均工资相同的函数,那么它们将获得相同的排名,并且都排名为1,那么你将看到这两个函数;所以你可以得到两个以上的结果。那可能是你想要的。如果没有,您可以通过定义如何打破联系来避免这种情况,可以使用
rank()
densed\u rank()

类似于@vkp的方法,但不需要连接回基表:

select function, avg_salary
from (
  select function, avg(salary) as avg_salary,
    rank() over (order by avg(salary)) as rnk_asc,
    rank() over (order by avg(salary) desc) as rnk_desc
  from tablename
  group by function
)
where rnk_asc = 1 or rnk_desc = 1;

F AVG_SALARY
- ----------
D        800
A        175
两个
rank()
调用将每个函数/平均值按顺序排列:

select function, avg(salary) as avg_salary,
  rank() over (order by avg(salary)) as rnk_asc,
  rank() over (order by avg(salary) desc) as rnk_desc
from tablename
group by function;

F AVG_SALARY    RNK_ASC   RNK_DESC
- ---------- ---------- ----------
D        800          6          1
B    4.7E+02          5          2
F        325          4          3
C        250          3          4
E        225          2          5
A        175          1          6
形成内联视图;然后,外部查询只选择在生成的列中排名1的行,这里是D和A

如果你有两个平均工资相同的函数,那么它们将获得相同的排名,并且都排名为1,那么你将看到这两个函数;所以你可以得到两个以上的结果。那可能是你想要的。如果没有,您可以通过定义如何断开连接来避免它,可以使用
rank()
densite\u rank()

如果您想返回一个最小/最大行,那么在避免两个不同的顺序时,您可能会得到一个更好的计划:

select function, avg_salary
from (
  select function, avg(salary) as avg_salary,
    ROW_NUMBER() over (order by avg(salary)) as rnk_asc,
    COUNT(*) over () as cnt
  from tablename
  group by function
)
where rnk_asc = 1 or rnk_asc = cnt;
注意,如果有两行具有相同的最大值(没有行,其中
rnk_asc=cnt
),则排名将失败。

如果您希望只返回一行最小值/最大值,则通过以下方法避免两个不同的顺序,您可能会得到更好的计划:

select function, avg_salary
from (
  select function, avg(salary) as avg_salary,
    ROW_NUMBER() over (order by avg(salary)) as rnk_asc,
    COUNT(*) over () as cnt
  from tablename
  group by function
)
where rnk_asc = 1 or rnk_asc = cnt;

注意,如果有两行具有相同的最大值(没有
rnk_asc=cnt
的行),则排名将失败。

哦,它可以工作。非常感谢。那很容易。若你们在意的话,在最后一条通道中,它应该在你们的解决方案中按t.函数分组,但无论如何它都是完美的:)哦,它是有效的。非常感谢。那很容易。若你们在意的话,在最后一条通道中,它应该在你们的解决方案中按t.函数分组,但无论如何它都是完美的:)是的,这更优雅。非常感谢您的关注和帮助:)您也有一个小错误,因为我需要的是AVG not SUM,但您的想法很棒。谢谢你1:)附言。我看你已经修复了你的错误::)@RIPI-我已经注意到并纠正了,对不起。(只注意到‘因为我对vkp有不同的答案!)是的,这更优雅。非常感谢您的关注和帮助:)您也有一个小错误,因为我需要的是AVG not SUM,但您的想法很棒。谢谢你1:)附言。我看你已经修复了你的错误::)@RIPI-我已经注意到并纠正了,对不起。(只注意到‘因为我对vkp有不同的答案!)您不应该在GROUPBY子句中使用别名<代码>按功能分组,而不是按功能分组。但是你也没有显示实际的平均值,只是找到了函数。我猜它只需要在外部选择列表中选择
z.avgSal
?啊,是的!打字错误谢谢您不应该在GROUPBY子句中使用别名<代码>按功能分组,而不是按功能分组。但是你也没有显示实际的平均值,只是找到了函数。我猜它只需要在外部选择列表中选择
z.avgSal
?啊,是的!打字错误谢谢您只需避免一个窗口排序;通过分析,你不可能同时找到最小和最大聚合,这会忽略索引-不确定这是否是你所想的。但这还是稍微好一点。@AlexPoole:我习惯于处理大量数据(DWH,虽然不在PG上),少一种排序可能会有很大的不同:)只避免一种窗口排序;通过分析,你不可能同时找到最小和最大聚合,这会忽略索引-不确定这是否是你所想的。但这还是稍微好一点。@AlexPoole:我习惯于处理大量数据(DWHs,虽然不在PG上),少一种排序可能会有很大的不同:)