Hereβs my deliberately verbose solution using DataFrames.jl and SplitApplyCombine.jl that produces the same result as my original SQL query:
julia> using DataFrames
julia> using SplitApplyCombine: innerjoin
julia> exchange_rates = DataFrame(time = [1,4,5,7,9,10,11], rate = [1.0,1.1,1.5,2.0,1.8,1.7,1.9])
7Γ2 DataFrame
β Row β time β rate β
β β Int64 β Float64 β
βββββββΌββββββββΌββββββββββ€
β 1 β 1 β 1.0 β
β 2 β 4 β 1.1 β
β 3 β 5 β 1.5 β
β 4 β 7 β 2.0 β
β 5 β 9 β 1.8 β
β 6 β 10 β 1.7 β
β 7 β 11 β 1.9 β
julia> trades = DataFrame(time = 1:12)
12Γ1 DataFrame
β Row β time β
β β Int64 β
βββββββΌββββββββ€
β 1 β 1 β
β 2 β 2 β
β 3 β 3 β
β 4 β 4 β
β 5 β 5 β
β 6 β 6 β
β 7 β 7 β
β 8 β 8 β
β 9 β 9 β
β 10 β 10 β
β 11 β 11 β
β 12 β 12 β
julia> trade_time(trade::DataFrameRow)::Int64 = trade.time
trade_time (generic function with 1 method)
julia> exchange_rate_time(exchange_rate::DataFrameRow)::Int64 = exchange_rate.time
exchange_rate_time (generic function with 1 method)
julia> trade_and_exchange_rate(trade::DataFrameRow, exchange_rate::DataFrameRow)::NamedTuple{(:trade, :rate),Tuple{Int64,Float64}} = (trade = trade.time, rate = exchange_rate.rate)
trade_and_exchange_rate (generic function with 1 method)
julia> exchange_rate_time_search(exchange_rate_times::Array{Int64,1}, trade_time::Int64)::Int64 = maximum(filter(time -> time <= trade_time, exchange_rate_times))
exchange_rate_time_search (generic function with 1 method)
julia> trade_exchange_rate_join_condition(trade_time::Int64, exchange_rate_time::Int64)::Bool = exchange_rate_time == exchange_rate_time_search(exchange_rates.time, trade_time)
trade_exchange_rate_join_condition (generic function with 1 method)
julia> trades_and_exchange_rates = DataFrame(
innerjoin(
trade_time,
exchange_rate_time,
trade_and_exchange_rate,
trade_exchange_rate_join_condition,
eachrow(trades),
eachrow(exchange_rates)
)
)
12Γ2 DataFrame
β Row β trade β rate β
β β Int64 β Float64 β
βββββββΌββββββββΌββββββββββ€
β 1 β 1 β 1.0 β
β 2 β 2 β 1.0 β
β 3 β 3 β 1.0 β
β 4 β 4 β 1.1 β
β 5 β 5 β 1.5 β
β 6 β 6 β 1.5 β
β 7 β 7 β 2.0 β
β 8 β 8 β 2.0 β
β 9 β 9 β 1.8 β
β 10 β 10 β 1.7 β
β 11 β 11 β 1.9 β
β 12 β 12 β 1.9 β
Just the source code:
using DataFrames
using SplitApplyCombine: innerjoin
exchange_rates = DataFrame(time = [1,4,5,7,9,10,11], rate = [1.0,1.1,1.5,2.0,1.8,1.7,1.9])
trades = DataFrame(time = 1:12)
trade_time(trade::DataFrameRow)::Int64 = trade.time
exchange_rate_time(exchange_rate::DataFrameRow)::Int64 = exchange_rate.time
trade_and_exchange_rate(trade::DataFrameRow, exchange_rate::DataFrameRow)::NamedTuple{(:trade, :rate),Tuple{Int64,Float64}} = (trade = trade.time, rate = exchange_rate.rate)
exchange_rate_time_search(exchange_rate_times::Array{Int64,1}, trade_time::Int64)::Int64 = maximum(filter(time -> time <= trade_time, exchange_rate_times))
trade_exchange_rate_join_condition(trade_time::Int64, exchange_rate_time::Int64)::Bool = exchange_rate_time == exchange_rate_time_search(exchange_rates.time, trade_time)
trades_and_exchange_rates = DataFrame(
innerjoin(
trade_time,
exchange_rate_time,
trade_and_exchange_rate,
trade_exchange_rate_join_condition,
eachrow(trades),
eachrow(exchange_rates)
)
)