2

次の構造を持つ 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
4

2 に答える 2

2

場合によってORA-00907: missing right parenthesisは、まさにそれを意味します。対応する右ブラケットのない左ブラケットがあります。ただし、括弧で囲まれたステートメントの一部の構文エラーによってスローされることもあります。

これが 2 番目の原因です。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() を使用することをお勧めします。分析関数は非常に強力です。 詳細をご覧ください

ROWN_NUMBER()、RANK()、および DENSE_RANK() は、上位n 個の問題に適用できます。それらの 1 つを使用して、最初の問題を解決することもできます。


「ただし、平均利益はゼロです。」

それはおそらくデータの問題です。の数値の 1 つ(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

これにより、上部の結果が null でないことが保証されます (少なくとも 1 人のアーティストが両方の列に値を持っている場合)。

于 2012-10-07T11:18:00.037 に答える
0

最初の質問 - Oracle は、行が取得される順序を保証しません。したがって、最初に注文してから、注文セットを制限する必要があります。SELECT * from ( SELECT A1.* 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

2 番目の質問: LIMIT 1 が間違っていると思います (テストしていません)。そのキーワードは、一括収集で使用するためのものです。

于 2012-10-07T11:21:21.893 に答える