But as to the original question as originally asked, the inner product of sparse vectors will always return a scalar (because it’s still smaller and more efficient than a 1x1 empty sparse matrix). But matrices make no such exception, so you can use this:
julia> view(J, :, 1:1)' * view(J, :, 2:2) # N*1 matrices
1×1 SparseMatrixCSC{Float64, Int32} with 0 stored entries:
⋅
julia> view(J, :, 1:1)' * view(J, :, 2) # or a matrix-vector product
1-element SparseVector{Float64, Int32} with 0 stored entries
But the built-in multiplication is still very likely to outperform your original function built on this.