我的表:
ID NUM VAL
1 1 Hello
1 2 Goodbye
2 2 Hey
2 4 What's up?
3 5 See you
如果我想返回每个ID的最大数量,那就非常干净了:
SELECT MAX(NUM) FROM table GROUP BY (ID)
但是如果我想获取与每个ID的每个数字的最大值相关联的值呢?
为什么我不能这样做:
SELECT MAX(NUM) OVER (ORDER BY NUM) FROM table GROUP BY (ID)
为什么会出错?我想让这个选择按ID分组,而不是为每个窗口单独分区......
编辑:错误是“不是GROUP BY表达式”。
答案 0 :(得分:14)
您可以使用MAX() KEEP(DENSE_RANK LAST...)
功能:
with sample_data as (
select 1 id, 1 num, 'Hello' val from dual union all
select 1 id, 2 num, 'Goodbye' val from dual union all
select 2 id, 2 num, 'Hey' val from dual union all
select 2 id, 4 num, 'What''s up?' val from dual union all
select 3 id, 5 num, 'See you' val from dual)
select id, max(num), max(val) keep (dense_rank last order by num)
from sample_data
group by id;
答案 1 :(得分:4)
使用窗口函数时,不再需要使用GROUP BY,这就足够了:
select id,
max(num) over(partition by id)
from x
实际上你可以在不使用窗口函数的情况下得到结果:
select *
from x
where (id,num) in
(
select id, max(num)
from x
group by id
)
输出:
ID NUM VAL
1 2 Goodbye
2 4 What's up
3 5 SEE YOU
http://www.sqlfiddle.com/#!4/a9a07/7
如果您想使用窗口功能,可以这样做:
select id, val,
case when num = max(num) over(partition by id) then
1
else
0
end as to_select
from x
where to_select = 1
或者这个:
select id, val
from x
where num = max(num) over(partition by id)
但由于不允许这样做,你必须这样做:
with list as
(
select id, val,
case when num = max(num) over(partition by id) then
1
else
0
end as to_select
from x
)
select *
from list
where to_select = 1
答案 2 :(得分:3)
如果您希望获得包含MAX(num) GROUP BY id
值的 行 ,这往往是一种常见模式......
WITH
sequenced_data
AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY id ORDER BY num DESC) AS sequence_id,
*
FROM
yourTable
)
SELECT
*
FROM
sequenced_data
WHERE
sequence_id = 1
修改强>
我不知道TeraData是否允许这样做,但逻辑似乎有意义......
SELECT
*
FROM
yourTable
WHERE
num = MAX(num) OVER (PARTITION BY id)
或者也许......
SELECT
*
FROM
(
SELECT
*,
MAX(num) OVER (PARTITION BY id) AS max_num_by_id
FROM
yourTable
)
AS sub_query
WHERE
num = max_num_by_id
这与我之前的回答略有不同;如果多个记录与同一个MAX(num)
绑定,则会返回所有记录,另一个答案将只返回一个。
修改强>
在您提议的SQL中,错误与OVER()
子句包含不在GROUP BY中的字段这一事实有关。这就像试图这样做......
SELECT id, num FROM yourTable GROUP BY id
num
无效,因为对于返回的每一行,该字段中可能有多个值(返回的行由GROUP BY id
定义)。
以同样的方式,您不能将num
放在OVER()
子句中。
SELECT
id,
MAX(num), <-- Valid as it is an aggregate
MAX(num) <-- still valid
OVER(PARTITION BY id), <-- Also valid, as id is in the GROUP BY
MAX(num) <-- still valid
OVER(PARTITION BY num) <-- Not valid, as num is not in the GROUP BY
FROM
yourTable
GROUP BY
id
如果您无法在OVER()
子句中指定内容,并且(我认为)何时可以显示答案,请参阅此问题:over-partition-by-question