3

(アドバンテージ データベース サーバー) 監査目的で決して削除されないサービス プロバイダーのテーブルがあります。開始日と終了日があります。名前や住所などの変更の場合、既存の行に終了日が付けられ、新しい行が作成され、変更されたデータに新しい開始日が割り当てられます。

これらのプロバイダーへの支払いの処理中に、プロバイダー名、住所、識別子 (ProvID)、および支払総額を一覧表示する概要ページが必要です。これは、SUM() と GROUP BY を使用したかなり単純なクエリで実行されます。

この問題は、指定されたプロバイダー ID に 2 つ以上の行がある場合に発生します。行が重複してしまいます (キャッチされない場合、そのプロバイダーへの複数の支払いが発生する可能性があります)。

私が最初に考えたのは、サブセレクトのようなもの (醜いが、かなり速く実行される) を使用することでした:

SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (p.EndDate IS NULL or p.EndDate = (SELECT Max(EndDate) FROM
   provider lu WHERE lu.ProvID = s.ProvID))

残念ながら、これでも 2 つの行が見つかりました。NULL の EndDate 用に 1 行、MAX(EndDate) 用に 1 行。

他の場合 (たとえば、特定の日付に提供されるサービスの適切な ProvID を見つける) では、これを処理します。

p.EndDate is null or (s.ServiceDate BETWEEN p.StartDate AND p.EndDate)

残念ながら、問題のクエリは集計を使用した GROUP BY であるため、運行日は利用できません。

助言がありますか?

編集:私が探しているのは、存在する場合は NULL EndDate を持つ行、または NULL 行が存在しない場合は Max(EndDate) を持つ行です。これは、たとえば、サプライヤーが昨日解雇されたが、先週は働いていた場合をカバーしており、来週には支払いを行う予定です。

4

5 に答える 5

4

したがって、終了日が NULL の行がある場合は、その行が必要であると思いますが、それ以外の場合は、終了日が最大の行が必要ですか?

ADS についてはよくわかりませんが、SQL Server では次のように動作します。

SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (COALESCE(p.EndDate, '2037-01-01') = (
   SELECT Max(COALESCE(EndDate, '2037-01-01')) FROM
   provider lu WHERE lu.ProvID = s.ProvID)
)

COALESCE演算子は最初のnull 以外のパラメーターを返すため、これは基本的に null を遠い将来の時間に設定するだけなので、SELECT MAX は NULL の終了日がある場合にそれを提供します。

于 2009-09-24T15:55:17.050 に答える
3

2番目の条件では、NULL EndDateがない場合にのみ最大値を取得する必要があります

SELECT ... FROM service s
INNER JOIN provider p ON p.ProvID = s.ProvID
AND (   p.EndDate IS NULL 
     or (p.EndDate = (SELECT Max(EndDate) 
                        FROM provider lu 
                       WHERE lu.ProvID = s.ProvID)
         AND NOT EXISTS (SELECT NULL 
                           FROM provider lu 
                          WHERE lu.ProvID = s.ProvID 
                            AND lu.EndDate IS NULL)
        )
    )
于 2009-09-24T15:53:13.587 に答える
0

おそらく、2 番目のテーブルの代わりにサブクエリを使用します。

SELECT ... FROM service s
INNER JOIN (SELECT ..., Max(EndDate) FROM
   provider lu WHERE lu.ProvID = s.ProvID GROUP BY ...) p ON p.ProvID = s.ProvID

これは、最大終了日がない場合に NULL が返されることを前提としています。

于 2009-09-24T15:51:16.653 に答える
0

あなたが参照しているのは、データ ウェアハウスのタイプ 2 ディメンションです。

適切なデータを取得するには、IDStartDate および EndDate で結合する必要があります。

OTTOMHコード

SELECT TransactionId, TransactionType
FROM TransactionList Tx
    INNER JOIN TransactionType TxType
        ON Tx.TransactionTypeId = TxType.TxTypeId
        AND Tx.TransactionDate Between TxType.StartDate and TxType.EndDate
于 2009-09-24T15:53:08.567 に答える
0

プロバイダー テーブルで現在の日付を示しているものは何ですか? EndDate=NULL、EndDate=Max(EndDate) または EndDate='9999-01-01'? 3 つすべてが有効な選択ですが、これは明確であるべきです。そうでないと、この特定のクエリをどれほど巧妙に作成しても、常にクエリで重複する行が発生することになるからです。したがって、プロバイダーテーブルでそれを修正することをお勧めします。そうすれば、次のようなものが機能するはずです。

select p.name, p.address, p.id, sum(s.amount)
  from provider p
  join service s on p.id=s.provider_id
where p.endDate is NULL
group by p.name, p.address, p.id
于 2009-09-24T16:03:00.153 に答える