SQL:ORDER BYのでUNIONクエリでトップ1使い方
-
20-08-2019 - |
質問
私は
以下のような表を持っています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
私はこれが起こる理由として手掛かりを持っていないのですか?任意の提案ですか?
解決
これは、このように動作します:
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'
他のヒント
労働組合の一部であるSELECT文の並び順は無視されます。したがって、あなたのTOP 1は、いくつかのarbitaryレコード(テーブルのクラスタ化されたキーによって可能性が最初のレコード)を選択されます。
ORDER BYが無効です...
私は
..あなたが探していた結果を得るために、いくつかのランクとケースステートメント策略で共通テーブル式を使用して急ごしらえし、汚れたブツを後処理します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)からの結果を使用し...検索日後にあるものに結果を分けます。ます。
ランク()関数は、その後、私たちはファッションを降順で効果的な日付順... CASE文はリストを区切るために使用するのと同じ基準でパーティションを作成することで、リストをソートします。これは、「過去」のリストを取得し、それが最新だようになります「過去」エントリランク1 ..
次に、クエリのユニオン部分で..
上の部分では、我々は1を返します。「過去」リスト(CUR = 0)と「過去」リストの最初のエントリ..(ソート= 1)。。からのランクと日付を取得していますレコード(または0検索日前にあるレコードがない場合)..
その後、我々組合その「現在」のリストからレコードのすべてと(CUR = 1)
は、その後、最後に...私たちは私たちに、現在のすべてのレコード、および「最新の」前のレコードを与える効力発生日であること... UNIONの結果を取り、順番ます。
私は上記のクエリは使用して、<と>の代わりに<=と> =のことで2009年5月1日を除くされていると信じています。