19

私は以下のようなテーブルを持っています

Rate Effective_Date
---- --------------
5.6  02/02/2009
5.8  05/01/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

現在の日付以降に有効なすべてのレートを見つけることになっています。したがって、現在の実効レートを取得するには、

SELECT TOP 1 * from table 
where effective_date < '05/05/2009' 
order by effective date desc

現在の日付以降のレートの場合、クエリは

SELECT * from table 
where effective_date > '05/05/2009'

これらの2つの結果を組み合わせるために、私はユニオンを次のように使用します

SELECT TOP 1 * from table 
where effective_date < '05/05/2009' 
order by effective date desc

UNION

SELECT * from table 
where effective_date > '05/05/2009'

期待される結果は

Rate Effective Date
---- --------------
5.8  05/01/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

しかし、私は実際の結果を次のように取得します

Rate Effective Date
---- --------------
5.6  02/02/2009
5.4  06/01/2009
5.8  12/01/2009
6.0  03/15/2009

なぜこれが起こるのか私にはわかりませんか?助言がありますか?

4

4 に答える 4

29

これは次のように機能します。

select *
from (
    select top 1 *
    from table
    where effective_date <= '05/05/2009'
    order by effective_date desc
) as current_rate

union all

select *
from table
where effective_date > '05/05/2009'
于 2009-05-09T06:32:46.287 に答える
9

ユニオンの一部であるselectステートメントのOrderByは無視されます。したがって、TOP 1は任意のレコード(テーブルのクラスター化されたキーによる最初のレコードの可能性が高い)を選択しています。

于 2009-05-09T06:36:51.940 に答える
5

ユニオンで使用する場合、OrderByは無効です。

Common Table ExpressionとRankおよびCaseステートメントのトリックを使用して、手っ取り早く汚いものを作成し、探している結果を取得しました。

WITH CTE_RATES ( RATE, EFFECTIVE_DATE, CUR, SORT )
AS (
    SELECT 
        Rate,
        Effective_date,
        CASE WHEN Effective_date > '5/5/2009' THEN 1
             ELSE 0
        END,
        RANK() OVER (PARTITION BY
                         CASE WHEN EFFECTIVE_DATE > '5/5/2009' THEN 1
                              ELSE 0
                         END
                     ORDER BY EFFECTIVE_DATE DESC)
    FROM TestTable
)

SELECT RATE, EFFECTIVE_DATE
FROM (
    SELECT RATE, EFFECTIVE_DATE 
    FROM CTE_RATES 
    WHERE CUR = 0 AND SORT = 1

    UNION ALL

    SELECT RATE, EFFECTIVE_DATE
    FROM CTE_RATES
    WHERE CUR = 1
    ) AS QRY
ORDER BY EFFECTIVE_DATE

何が起こっているのかを説明するには...

CTEは、クエリから返されるレート、日付、現在のフラグ、および並べ替えフラグを定義します。

CASEは、結果を検索日より前の結果と検索日より後の結果に分けます。ユニオンのケース(Cur)の結果を使用して、パーティションリストから結果を取得します。

次に、Rank()関数は、CASEステートメントがリストを区切るために使用するのと同じ基準でパーティションを作成することによってリストを並べ替えます。次に、発効日で降順で並べ替えます。これにより、「過去」のリストが取得され、最新の「過去」のエントリランク1になります。

次に、クエリの和集合部分で。

上部では、「過去」リスト(cur = 0)と「過去」リストの最初のエントリからランクと日付を取得しています。(sort = 1).. 1レコード(または検索日より前のレコードがない場合は0)。

次に、それを「現在の」リストのすべてのレコードと結合します(cur = 1)

そして最後に..UNIONの結果を取得し、発効日までにすべての現在のレコードと「最新の」以前のレコードを提供するように注文します。

于 2009-05-09T06:37:42.873 に答える
1

上記のクエリは、<=と> =の代わりに<と>を使用して、2009年5月1日を除外していると思います。

于 2009-05-09T06:28:32.817 に答える