如何在Oracle中显示具有最高值的记录?

时间:2012-10-07 10:30:23

标签: sql oracle limit top-n

我有4个表格,结构如下:

artist

artistID lastname firstname nationality dateofbirth datedcease

work

workId title copy medium description artist ID

Trans

TransactionID Date Acquired Acquistionprice datesold askingprice salesprice customerID workID

Customer

customerID lastname Firstname street city state zippostalcode country areacode phonenumber email

第一个问题是哪位艺术家的作品最多artsold,以及有多少艺术家作品被出售。

我的SQL查询是:

SELECT * From dtoohey.artist A1 
INNER JOIN 
(
    SELECT COUNT(W1.ArtistID) AS COUNTER, artistID  FROM dtoohey.trans T1
    INNER JOIN dtoohey.work W1
    ON W1.workid = T1.Workid
    GROUP BY W1.artistID
) TEMP1
ON TEMP1.artistID = A1.artistID
WHERE A1.artistID = TEMP1.artistId
ORDER BY COUNTER desc;

我要获得整个表格,但我只想显示第一行,这是最高计数我该怎么做?

我尝试插入WHERE ROWNUM <=1,但它显示的艺术家ID为1

qns 2是艺术家作品的销售额导致平均利润最高的(即,艺术家每次出售作品时的平均利润),以及该金额是多少。

我的SQL查询是:

SELECT A1.artistid, A1.firstname FROM
(
    SELECT 
        (salesPrice - AcquisitionPrice) as profit, 
        w1.artistid as ArtistID 
    FROM dtoohey.trans T1
    INNER JOIN dtoohey.WORK W1
    on W1.workid = T1.workid
) TEMP1
INNER JOIN dtoohey.artist A1
ON A1.artistID = TEMP1.artistID
GROUP BY A1.artistid
HAVING MAX(PROFIT) = AVG(PROFIT);

我无法执行它

我在下面尝试过查询,但仍然无法让它继续错误地使用右括号

SELECT A1.artistid, A1.firstname, TEMP1.avgProfit
FROM 
(
    SELECT 
        AVG(salesPrice - AcquisitionPrice) as avgProfit, 
        W1.artistid as artistid
    FROM dtoohey.trans T1
    INNER JOIN dtoohey.WORK W1
    ON W1.workid = T1.workid
    GROUP BY artistid
    ORDER BY avgProfit DESC
    LIMIT 1
) TEMP1
INNER JOIN dtoohey.artist A1
ON A1.artisid = TEMP1.artistid

2 个答案:

答案 0 :(得分:2)

有时ORA-00907: missing right parenthesis意味着:我们有一个左括号而没有匹配的右括号。但它也可能被括号括起来的语句的一部分语法错误抛出。

这是第二个原因:LIMIT是Oracle无法识别的Mysql命令。您可以在此处使用分析函数:

SELECT A1.artistid, A1.firstname, TEMP1.avgProfit
FROM 
(
    select  artistid
            , avgProfit
            , rank() over (order by avgProfit desc) as rnk
    from (
        SELECT 
            AVG(salesPrice - AcquisitionPrice) as avgProfit, 
            W1.artistid as artistid
        FROM dtoohey.trans T1
        INNER JOIN dtoohey.WORK W1
        ON W1.workid = T1.workid
        GROUP BY artistid
    ) 
) TEMP1
INNER JOIN dtoohey.artist A1
    ON A1.artisid = TEMP1.artistid
where TEMP1.rnk = 1

这使用RANK()函数,如果多个艺术家达到相同的平均利润,它将返回多行。您可能希望使用ROW_NUMBER()。分析功能可以非常强大。 Find out more

您可以将ROWN_NUMBER(),RANK()和DENSE_RANK()应用于任何top- n 问题。您也可以使用其中一个来解决您的第一个问题。


  

“但平均利润为空。”

这可能是一个数据问题。如果(salesPrice - AcquisitionPrice)中的一个数字为null,则结果将为null,并且不会包含在平均值中。如果艺术家的所有行都为null,则AVG()将为null。

实际上,排序顺序会将NULL放在最后。但是,当PARTITION BY子句按AvgProfit desc排序时,将NULL结果置于等级1.解决方案是在窗口子句中使用NULLS LAST:

            , rank() over (order by avgProfit desc nulls last) as rnk

这将保证您在顶部显示非空结果(假设您的至少一位艺术家在两列中都有值)。

答案 1 :(得分:0)

第一个问题 - Oracle不保证检索行的顺序。因此,您必须先订购然后限制有序集。 SELECT * from(来自 SELECT A1。*来自dtoohey.artist A1 内部联接 (     SELECT COUNT(W1.ArtistID)AS COUNTER,artistID来自dtoohey.trans T1     INNER JOIN dtoohey.work W1     ON W1.workid = T1.Workid     GROUP BY W1.artistID )TEMP1 ON TEMP1.artistID = A1.artistID 在哪里A1.artistID = TEMP1.artistId 按订单排序 )WHERE ROWNUM = 1

第二个问题:我相信(尚未测试)你有LIMIT 1错误。该关键字用于批量收集。