0

2つのテーブルがあります:

CREATE TABLE STORE ( 
  ID INTEGER NOT NULL,  
  MEDICINE_ID INTEGER NOT NULL,  
  SHIPMENT_ID INTEGER NOT NULL,  
  PACKAGE_ID INTEGER NOT NULL,  
  QUANTITY INTEGER NOT NULL);  

CREATE TABLE ORDERS (  
  ID INTEGER NOT NULL,  
  CLIENT_ID INTEGER NOT NULL,
  STORE_ITEM_ID INTEGER NOT NULL,
  QUANTITY INTEGER NOT NULL,
  ORDERDATE DATE NOT NULL,
  STATE INTEGER DEFAULT 1 NOT NULL);

ここでは、フィールドのみを記述し、ジェネレーター、トリガー、キーなどは記述していません。

次のビューでは、日付ごとに最も人気のある薬を選択します。

CREATE VIEW ORDERS_STORE_QTY
AS
SELECT
  O1.ORDERDATE,
  S1.MEDICINE_ID,
  SUM(O1.QUANTITY) AS QTY
FROM ORDERS O1
INNER JOIN STORE S1 ON (S1.ID = O1.STORE_ITEM_ID)
WHERE O1.STATE=5 /* the closed order */
GROUP BY O1.ORDERDATE, MEDICINE_ID
ORDER BY O1.ORDERDATE, SUM(O1.QUANTITY) DESC

次に、ビューとそれ自体の左結合を実行し、条件で要約数量を比較します。

SELECT T1.ORDERDATE, T1.MEDICINE_ID, T1.QTY
  FROM ORDERS_STORE_QTY T1
  LEFT OUTER JOIN ORDERS_STORE_QTY T2
  ON (
        T1.ORDERDATE = T2.ORDERDATE
        AND
        T2.QTY > T1.QTY 
     )
   GROUP BY T1.ORDERDATE, T1.MEDICINE_ID, T1.QTY
   HAVING COUNT(T2.MEDICINE_ID) < 5
   ORDER BY T1.ORDERDATE, T1.QTY DESC

1日あたりの総量がすべて異なっていれば問題ありませんでした。私の仕事は「最高の」薬を1日5つに制限することですが、繰り返し量があることがあるので、シーケンス0、1、2、3、4の代わりに0、1、2、2、2、3、4 取得 しました、たとえば
5 。

クエリを変更して(ジェネレーターを使用せず、非正規化も使用しないことをお勧めします)、実際に行数を制限するにはどうすればよいですか?

すべてのコードは純粋なSQLに近く(私はそう願っています)、Firebird2.5用に書かれています。

4

2 に答える 2

1

自己結合の on 句を次のように変更できると思います。

ON T1.ORDERDATE = T2.ORDERDATE AND 
   (T2.QTY > T1.QTY or
    (T2.QTY = T1.QTY and t2.Medicine_ID < t1.Medicine_ID)
   )

これが行うことは、厳密な順序付けを課すことにより、結びつきをなくすことです。最初は数量順、次に薬 ID 順です。

ああ、ウィンドウ関数 (row_number()) をサポートするデータベースを使用した場合、これははるかに簡単になります;)

于 2012-06-20T18:18:25.093 に答える
0

DISTINCTステートメントにキーワードを追加して、SELECT重複を排除してみてください。

于 2012-06-20T18:17:22.950 に答える