3

さまざまなテーブルのカウントの合計を計算しました。これは、各 に対して 1 回ずつ、2 回行われますperformanceID。今、私は2つの合計の合計を取得したい.

以下は、現在行っている2つの合計のコードです。

    SELECT SUM((COUNT (BookingID) * CategoryPrice)) AS TotalAmount
    FROM Booking, Production
    WHERE Booking.PerformanceID IN(SELECT PerformanceID FROM Performance WHERE PerformanceID = '1')
    and Production.ProductionID IN 
    (SELECT ProductionID FROM Performance WHERE PerformanceID = '1') 
    GROUP BY BookingID, CategoryPrice
    UNION ALL
    SELECT SUM((COUNT (BookingID) * CategoryPrice)) AS TotalAmount
    FROM Booking, Production
    WHERE Booking.PerformanceID IN(SELECT PerformanceID FROM Performance WHERE PerformanceID = '2')
    and Production.ProductionID IN 
    (SELECT ProductionID FROM Performance WHERE PerformanceID = '2')
     GROUP BY BookingID, CategoryPrice

私が得る結果は次のとおりです。

合計金額
-----------
         70
         60

ここで2つの合計をどのように合計しますか?

4

2 に答える 2

7

FGITWと競合するつもりはありませんが、このクエリについて何か言わなければなりません...

空白を追加すると、私の言いたいことがわかると思います。

SELECT SUM( (COUNT(BookingID) * CategoryPrice) ) AS TotalAmount
  FROM Booking
     , Production
 WHERE Booking.PerformanceID IN ( SELECT PerformanceID 
                                   FROM Performance 
                                  WHERE PerformanceID = '1')
   AND Production.ProductionID IN ( SELECT ProductionID FROM Performance 
                                     WHERE PerformanceID = '1') 
 GROUP BY BookingID, CategoryPrice
 UNION ALL
SELECT SUM( (COUNT(BookingID) * CategoryPrice)) AS TotalAmount
  FROM Booking
     , Production
 WHERE Booking.PerformanceID IN ( SELECT PerformanceID 
                                    FROM Performance 
                                   WHERE PerformanceID = '2')
   AND Production.ProductionID IN ( SELECT ProductionID 
                                      FROM Performance 
                                     WHERE PerformanceID = '2')
 GROUP BY BookingID, CategoryPrice

クエリを分解すると、 2 つの行が返された唯一の理由は、分析関数とすべての結合です。

  1. との間でデカルト結合を行っています。これは、それぞれの行数を互いに乗算することを意味します。bookingproduction
  2. あなたの副選択performanceは、すでに知られている1つの値を返しています。それらを行う理由はまったくありません。
  3. 暗黙的に数値を文字列に変換し、再び数値に戻しています。
  4. ここでは、テーブルまたはインデックスを 8 回スキャンしています。

パフォーマンスごとに取得した合計金額が必要なように見えます。この場合、クエリは次のように簡略化できます。

SELECT SUM(bookings * CategoryPrice)
  FROM ( SELECT CategoryPrice , count(*) as bookings
           FROM Booking b
           JOIN performance per
             ON p.performanceid =  per.performanceid
           JOIN Production p
             ON p.productionid = per.productionid
          WHERE p.performanceid in (1, 2)
          GROUP BY CategoryPrice
                )

明示的な結合構文に注意してください。これは数十年前から存在しており、物事をより明確にし、間違いを防ぐのに役立ちます。このクエリは、両方のテーブルにインデックスがあると仮定して、bookingの 1つと の 1 つで、2 つの範囲スキャンを実行します。また、それがこのテーブルの主キーであると仮定して、一意のスキャンも実行します。productionperformanceidperformanceperformanceid

これが何をするかの説明として、ようやくスキーマを正しくすることができました! 2 つのパフォーマンスを選択し1ます2。次に、それらの公演に関連するすべての作品と、それらの作品に関連するすべての予約を選択します。含まれているテーブルによっては、これをさらに単純化できる場合がありますcategoryprice。次に、1 件あたりの予約数を取得し、categorypriceこれらの積を合計して合計値を算出します。

ちょっとしたアドバイスとして、クエリが正しいことを受け入れる前に、クエリから返されると予想される値を理解することを常にお勧めします。最高の人間は間違いを犯す可能性があり、間違いを犯します。返された値が正しくないことがわかるので、それらをキャッチできると役立ちます。

参考文献:

于 2012-05-06T11:12:52.900 に答える