我怎样才能获得每个国家的最大价值

时间:2018-04-28 14:13:03

标签: sql oracle

我正在使用oracle sql developer。我有两张桌子

交易:

╔════╤═══════╗
║ 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;

我应该更改以获得每个国家/地区的最大值?

6 个答案:

答案 0 :(得分:2)

这可能有效:

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;

希望这有帮助。

答案 1 :(得分:1)

传统方法不会使用子查询,只需joingroup by

SELECT u.country, MAX(t.value)
FROM users u LEFT JOIN
     transactions t
     ON u.id = t.id
GROUP BY u.country;

答案 2 :(得分:1)

这可能会得到所需的结果

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;

答案 3 :(得分:1)

您必须首先找到每个国家/地区的最大值并为性别执行另一次加入,例如:

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

答案 4 :(得分:1)

试试这个。

    __author__ = 'Sam'
import lxml.html as LH
from lxml import html
from lxml import etree
import xml.etree.ElementTree as ET

from collections import Counter


doc = ET.parse("data_science_assignment.txt")
root = doc.getroot()
# Initialise a list to append results to
# root = html.fromstring(doc)
art1 = ""
art2 = ""
art3 = ""
i = 0
# Loop through the pages to search for text
for page in root:
    id = page.findtext('docno',default='None')
    text = page.findtext('text/*',default='None')
    # text = page.attrib.get('text',None)
    if i==0:
        art1 = text
    elif i==1:
        art2 = text
    else:
        art3 = text
    i+=1


# article1 = art1.split()
# article2 = art2.split()
# article3 = art3.split()
# print article1
# print (len(article1) + len(article2) + len(article3))
dict1 = {}
dict2 = {}
dict3 = {}
words = []
words.extend(art1.split())
words.extend(art2.split())
words.extend(art3.split())
# print len(words)

for word in words:
    if word.lower() in art1:
        # print word.lower()
        if word.lower() in dict1:
            dict1[word.lower()] += 1
        else:
            dict1[word.lower()] = 1

for word in words:
    if word.lower() in art1:
        # print word.lower()
        if word.lower() in dict2:
            dict2[word.lower()] += 1
        else:
            dict2[word.lower()] = 1

for word in words:
    if word.lower() in art1:
        # print word.lower()
        if word.lower() in dict3:
            dict3[word.lower()] += 1
        else:
            dict3[word.lower()] = 1

# for k,v in dict1.iteritems():
#     print k,v
#Get words present in all the articles
dict4 = {}
check = []
for word in words:
    if word.lower() in dict1.keys() and word.lower() in dict2.keys() and word.lower() in dict3.keys():
        if word.lower not in dict4:
            dict4[word.lower()] = "-> [1," + str(dict1[word.lower()]) + "] -> " + "[2," + str(dict2[word.lower()]) + "] -> " + "[3," + str(dict3[word.lower()]) + "]"
for k,v in dict4.items():
        print(k,v)


dict5 = {}
# #get words present in only first two articles
for word in words:
    if word.lower() in dict1.keys() and word.lower() in dict2.keys() and word.lower() not in dict3.keys():
        if word not in dict5:
            dict5[word.lower()] = "-> [1," + str(dict1[word.lower()]) + "] -> " + "[2," + str(dict2[word.lower()]) + "]  "# + "[3," + str(dict3[word.lower()]) + "]"
for k,v in dict5.items():
        print(k,v)

演示:http://www.sqlfiddle.com/#!4/5f476/27/0

答案 5 :(得分:1)

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