Datatool, Two DB rows per table row, vertically ordered
\documentclass[a4paper]{article}
\usepackage{datatool}
\begin{document}
\DTLsetseparator{;}
\DTLloaddb[noheader,keys={id,item}]{test_db}{test.csv}
\begin{table}[htbp]
\count2=\DTLrowcount{test_db}
\count4 = \count2
\divide\count4 by 2
\count2=\count4
\advance\count2 by 1
\caption{Two database rows per tabular row}
\centering
\begin{tabular}{cc|cc}
\bfseries ID &
\bfseries Item &
\bfseries ID &
\bfseries Item
\DTLforeach*[\id<\count2]{test_db}{\id=id,\item=item}{%
\\
\id & \item
\count0=\id
\advance\count0 by \count4
\DTLforeach*[\id=\count0]{test_db}{\id=id,\item=item}{%
&\id &\item}
}
\end{tabular}
\end{table}
\end{document}
With the help of David Carlisle I managed to solve it. I modified his code a little bit to also support an odd number of rows in the CSV file. My modification is probably not the best way to do it, but I'm just getting started with LaTeX and it is so not like what I'm used to when it comes to programming.
\documentclass[a4paper]{article}
\usepackage{datatool}
\begin{document}
\DTLsetseparator{;}
\DTLloaddb[noheader,keys={id,item}]{test_db}{test.csv}
\DTLrowcount{test_db}
\begin{table}[htbp]
\count2=\DTLrowcount{test_db}
\count4 = \count2
\divide\count4 by 2
\count2=\count4
%%% modification start
\count10=\count2
\advance\count10 by \count4
\ifnum\count10=\DTLrowcount{test_db}
%even number of entries
\advance\count2 by 1
\else
%odd number of entries
\advance\count2 by 2
\advance\count4 by 1
\fi
%%% modification end
\caption{Two database rows per tabular row}
\centering
\begin{tabular}{cc|cc}
\bfseries ID &
\bfseries Item &
\bfseries ID &
\bfseries Item
\DTLforeach*[\id<\count2]{test_db}{\id=id,\item=item}{%
\\
\id & \item
\count0=\id
\advance\count0 by \count4
\DTLforeach*[\id=\count0]{test_db}{\id=id,\item=item}{%
&\id &\item}
}
\end{tabular}
\end{table}
\end{document}