2

単純な SQL クエリを分解できません。私は PostgreSQL を使用していますが、私の質問は他の RDBMS にも関連しています。

次の例を考えてみましょう。テーブル注文があり、合計金額が制限を超えた最初の注文を見つけたいと考えています。

drop table if exists orders cascade;

/**
Table with clients' orders
*/
create table orders(
date timestamp,
amount integer
/**
Other columns omitted
*/
);

/**
Populate with test data
*/
insert into orders(date,amount) 
values
('2011-01-01',50),
('2011-01-02',49),
('2011-01-03',2),
('2011-01-04',1000);

/**
Selects first order that caused exceeding of limit 
*/
create view first_limit_exceed
as
select min(date) from
(
    select  o1.date
    from orders o1,
         orders o2
    where o2.date<=o1.date
    group by o1.date
    having sum(o2.amount) > 100
) limit_exceed;

/**
returns "2011-01-03 00:00:00"
*/
select * from first_limit_exceed;

では、問題を少し難しくしてみましょう。いくつかの述語を満たす行のみの合計金額を見つけたいと考えてください。このような述語がたくさんあり、別のバージョンのビュー first_limit_exceed を作成すると、ひどいコード重複が発生します。したがって、パラメーター化されたビューを作成し、フィルター処理された行のセットまたは述語自体を渡す方法が必要です。Postgres では、クエリ言語関数をパラメーター化されたビューとして使用できます。しかし、Postgres では、関数が行のセットでも別の関数でもない引数として取得することは許可されていません。クライアント側または plpgsql 関数で文字列補間を引き続き使用できますが、エラーが発生しやすく、テストとデバッグが困難です。何かアドバイス?

4

2 に答える 2

2

以降PostgreSQL 8.4:

SELECT  *
FROM    (
        SELECT  *,
                SUM(amount) OVER (ORDER BY date) AS psum
        FROM    orders
        ) q
WHERE   psum > 100
ORDER BY
        date
LIMIT 1

必要な述語を内部クエリに追加します。

SELECT  *
FROM    (
        SELECT  *,
                SUM(amount) OVER (ORDER BY date) AS psum
        FROM    orders
        WHERE   date >= '2011-01-03'
        ) q
WHERE   psum > 100
ORDER BY
        date
LIMIT 1
于 2011-08-12T16:20:03.717 に答える
-1

データベースにあまりにも多くのコードを入れようとしているように思えます。特定の述語を満たす特定の関係の行に関心がある場合は、クライアント コードで適切な句を使用してselectステートメントを実行するだけです。where述語をパラメーターとして受け取るビューを持つことは、SQL が既にうまく解決している車輪を再発明することです。

一方、クエリ自体をデータベースに格納して、より大きなレポートに構成できるようにするという議論も見られます。この 2 つは、アプリケーション コードで処理する方が適切です。動的なSQL生成に適したライブラリ(sqlalchemyなど)を使用し、クエリ表現(sqlalchemy式オブジェクトは「pickleable」)をデータベースにブロブとして保存することで、そのような問題に取り組むことができます。

別の言い方をすれば、データベースは事実の代表者であり、知識をデータベースに保存します。アプリケーションにはユーザーの要求に応じる義務があります。データの変換を自分で定義していることに気付いた場合、知識を忠実に保存するだけでなく、実際のユーザーの要求を予測して実装することが重要です。

ビューは、スキーマが必然的に変更される場合に最もよく使用されるため、新しいスキーマについて知る必要のない古いアプリケーションを動作状態のままにしておくことができます。

于 2011-08-12T16:32:17.240 に答える