2012-10-07 57 views
2

我有4代表具有以下結構:如何在Oracle中顯示具有最高值的記錄?

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是銷售該藝術家的作品已經產生最高的平均利潤(IE)的平均利潤上的worksby的每個銷售取得藝術家),這是多少錢。

我的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 
+0

SO使用Q&A格式,這意味着每個線程有一個問題。然而,在這種情況下,這兩個問題是相關的,因爲它們是同一類問題。 – APC

回答

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)中的一個數字爲空,則結果將爲空,並且不會包含在平均值中。如果藝術家的所有行都爲空,則AVG()將爲空。

碰巧排序順序將最後放置NULL。但隨着PARTITION BY子句排序由AvgProfit desc,它將在NULL結果在排名1。解決的辦法是開窗子句中最後使用的NULL:

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

這將保證你在頂部有一個非空結果(至少爲您的一位藝術家提供兩列中的值)。

+0

嗨,我已經嘗試過,但在rnk – user1692068

+0

有一個錯誤無效的標識符對不起。具有諷刺意味的是,我發現括號的範圍是錯誤的。我編輯了我的答案,所以現在應該可以工作。 – APC

+0

好的謝謝你的工作alr。然而平均利潤爲零。 – user1692068

0

第一個問題 - Oracle不保證檢索行的順序。因此,您必須先訂購,然後限制訂購的產品。 SELECT * FROM(SELECT A1。*從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計數器遞減 )WHERE ROWNUM = 1

第二個問題:我相信(沒有測試過),你有LIMIT 1錯誤。該關鍵字用於批量收集。

相關問題