テーブルdbo.X
とDateTime
column Y
があり、何百ものレコードがある場合があります。
ストアドプロシージャにはパラメータ@CurrentDate
があります。上記の表のcolumn Y
の日付を見つけたいdbo.X
は@CurrentDate.
より小さく、最も近いです
どうやって見つけるの?
Where句は、@ CurrentDateより小さい日付を持つすべての行に一致します。これらの行は子孫であるため、TOP 1は現在の日付に最も近い日付になります。
SELECT TOP 1 *
FROM x
WHERE x.date < @CurrentDate
ORDER BY x.date DESC
DateDiff を使用して、その日付と入力が何であったかの間の日数または秒数で結果を並べます
このようなもの
select top 1 rowId, dateCol, datediff(second, @CurrentDate, dateCol) as SecondsBetweenDates
from myTable
where dateCol < @currentDate
order by datediff(second, @CurrentDate, dateCol)
私はこの問題に対してより良い解決策があると思います。
最終的なソリューションをサポートおよび説明するために、いくつかの画像を示します。
背景私のソリューションにはFXレートの表があります。これらは、異なる通貨の市場レートを表します。ただし、サービスプロバイダーにはレートフィードに問題があり、そのため一部のレートの値はゼロになっています。欠落しているデータに、欠落しているレートに時間的に最も近い同じ通貨のレートを入力します。基本的に、最も近い非ゼロレートのRateIdを取得し、それを代入します。 (これは私の例では示されていません。)
1)そのため、まずは欠落している料金情報を特定します:
2)次に、欠落していないレートを特定します。欠落していないレートを示すクエリ
3)このクエリは、魔法が発生する場所です。ここでは、削除できると仮定しましたが、クエリの効率/パフォーマンスを改善するために追加されました。行26の前提は、欠落/ゼロトランザクションと同じ日に代替トランザクションを見つけることです。魔法が起こるのは23行目です。Row_Number関数は、欠落しているトランザクションと欠落していないトランザクションの時間差が最短になるように、1から始まる自動番号を追加します。次に近いトランザクションのrownumは2などです。
25行目では、通貨の種類が一致しないように通貨を結合する必要があることに注意してください。つまり、AUD通貨をCHF値に置き換えたくありません。最も近い通貨が欲しい。
2つのデータセットをrow_numberと組み合わせて、最も近いトランザクションを識別する
4)最後に、RowNumが1であるデータを取得します最終クエリ
クエリの完全なクエリは次のとおりです。
; with cte_zero_rates as
(
Select *
from fxrates
where (spot_exp = 0 or spot_exp = 0)
),
cte_non_zero_rates as
(
Select *
from fxrates
where (spot_exp > 0 and spot_exp > 0)
)
,cte_Nearest_Transaction as
(
select z.FXRatesID as Zero_FXRatesID
,z.importDate as Zero_importDate
,z.currency as Zero_Currency
,nz.currency as NonZero_Currency
,nz.FXRatesID as NonZero_FXRatesID
,nz.spot_imp
,nz.importDate as NonZero_importDate
,DATEDIFF(ss, z.importDate, nz.importDate) as TimeDifferece
,ROW_NUMBER() Over(partition by z.FXRatesID order by abs(DATEDIFF(ss, z.importDate, nz.importDate)) asc) as RowNum
from cte_zero_rates z
left join cte_non_zero_rates nz on nz.currency = z.currency
and cast(nz.importDate as date) = cast(z.importDate as date)
--order by z.currency desc, z.importDate desc
)
select n.Zero_FXRatesID
,n.Zero_Currency
,n.Zero_importDate
,n.NonZero_importDate
,DATEDIFF(s, n.NonZero_importDate,n.Zero_importDate) as Delay_In_Seconds
,n.NonZero_Currency
,n.NonZero_FXRatesID
from cte_Nearest_Transaction n
where n.RowNum = 1
and n.NonZero_FXRatesID is not null
order by n.Zero_Currency, n.NonZero_importDate