我怎样才能获得每个国家的最大值
Posted
技术标签:
【中文标题】我怎样才能获得每个国家的最大值【英文标题】:how can i get max value for each country 【发布时间】:2018-04-28 14:13:02 【问题描述】:我正在使用 oracle sql 开发人员。我有两张桌子
交易:
╔════╤═══════╗
║ id │ value ║
╠════╪═══════╣
║ 1 │ 10 ║
╟────┼───────╢
║ 1 │ 20 ║
╟────┼───────╢
║ 2 │ 30 ║
╟────┼───────╢
║ 3 │ 40 ║
╚════╧═══════╝
和用户:
╔════╤═════════╤═════╗
║ id │ country │ sex ║
╠════╪═════════╪═════╣
║ 1 │ Germany │ m ║
╟────┼─────────┼─────╢
║ 2 │ Germany │ f ║
╟────┼─────────┼─────╢
║ 3 │ France │ m ║
╚════╧═════════╧═════╝
我想像这样为每个国家/地区获得最大值
╔════╤═════════╤═════╤══════════╗
║ id │ country │ sex │ maxvalue ║
╠════╪═════════╪═════╪══════════╣
║ 2 │ Germany │ f │ 30 ║
╟────┼─────────┼─────┼──────────╢
║ 3 │ France │ m │ 40 ║
╚════╧═════════╧═════╧══════════╝
我知道如何为每个用户获取最大值并加入表格
SELECT u.*, max
FROM users u
LEFT JOIN
(SELECT id, max(value) as max
FROM transactions
group by ID) t
on u.id = t.id;
我应该改变什么以获得每个国家的最大值?
【问题讨论】:
德国米在哪里? 如果事务表中 id = 1 的值为 20、30,那么预期的输出是什么?它会取代法国到德国吗? 应该同时显示 Id 1 的值也是 30 (10 + 20)。因此,id 1 和 id 2 的最大值是相同的。所以现在怎么办?为什么我们选择 2 或 1? 只有其中一个 【参考方案1】:这可能有效:
SELECT id, country, sex, value AS maxvalue FROM (
SELECT u.id, u.country, u.sex, COALESCE(t.value, 0) AS value
, ROW_NUMBER() OVER ( PARTITION BY u.country ORDER BY t.value DESC NULLS LAST ) AS rn
FROM users u LEFT JOIN transactions t
ON u.id = t.id
) WHERE rn = 1;
这将获取每个国家/地区的所有值并对其进行排名,然后仅检索排名最高的值。如果您也想打成平手,请使用RANK()
而不是ROW_NUMBER()
:
SELECT id, country, sex, value AS maxvalue FROM (
SELECT u.id, u.country, u.sex, COALESCE(t.value, 0) AS value
, RANK() OVER ( PARTITION BY u.country ORDER BY t.value DESC NULLS LAST ) AS rn
FROM users u LEFT JOIN transactions t
ON u.id = t.id
) WHERE rn = 1;
希望这会有所帮助。
【讨论】:
【参考方案2】:试试这个。
select tmp.country, tmp.maxvalue, tmp.id, users.sex from (
select users.country as country, max(transactions.value) as maxvalue, max(users.id) as id
from users
inner join transactions on users.id = transactions.id
group by users.country) tmp
inner join users on tmp.id = users.id;
演示:http://www.sqlfiddle.com/#!4/5f476/27/0
【讨论】:
【参考方案3】:传统方法不会使用子查询,而只是使用join
和group by
:
SELECT u.country, MAX(t.value)
FROM users u LEFT JOIN
transactions t
ON u.id = t.id
GROUP BY u.country;
【讨论】:
可能是 OP 也想通过sex
分组。示例预期数据与文本说明不匹配。
您的代码有效,但仅当我想显示国家和最大值时,当我想显示国家、最大值和性别时,我得到一个错误 - “错误报告 - SQL 错误:ORA-00979:不是 GROUP BY 表达式 00979. 00000 - "不是 GROUP BY 表达式""
嗨@gordonLinoff,我告诉过你;)
我不想按性别分组,但我想在表格中显示它
是的,很有趣。我期待这个线程的结束。我去吃爆米花。【参考方案4】:
这可能会得到所需的结果
SELECT u.id, u.country, u.sex, MAX(t.value)
FROM users u
LEFT JOIN transactions t ON u.id = t.id
GROUP BY u.id, u.country, u.sex;
【讨论】:
您的代码不起作用,它不显示每个国家/地区的最大值 我的查询显示 country 和 sex 的最大值,如果您只想要国家/地区的值而不是从两者中删除 u.id 和 u.sex select 和 group by 子句 错误报告 - SQL 错误:ORA-00979:不是 GROUP BY 表达式 00979。00000 - “不是 GROUP BY 表达式” *原因:*操作: 当您在使用聚合函数时,在 group by 子句中没有选定子句的所有字段时,会发生此错误。见this 我的真实桌子要大得多,而且我有超过 2 种性别【参考方案5】:您必须首先找到每个国家/地区的最大值,然后再为性别进行连接,如下所示:
SELECT u.*, t.value
FROM transactions t
INNER JOIN users u ON t.id = u.id
INNER JOIN
(SELECT us.country, MAX(tr.value) AS max_value
FROM transactions tr
INNER JOIN users us ON tr.id = us.id
GROUP BY us.country) sub ON t.value = sub.value AND u.country = sub.country
【讨论】:
【参考方案6】:select * from (
SELECT t.ID, u.COUNTRY, T.VALUE,
row_number() over(partition by u.country order by t.value desc) rn
FROM USERS u , transactions t
where u.id = t.id)
where rn = 1
【讨论】:
以上是关于我怎样才能获得每个国家的最大值的主要内容,如果未能解决你的问题,请参考以下文章