This has some limitations on the tabular: you can't have \multicolumn in the last row, nor optional arguments to \\ (this one may be lifted off).
\documentclass{article}
\usepackage{environ}
\makeatletter
\NewEnviron{mtabular}[3][c]{%
\begingroup
\renewcommand{\multicolumn}[3]{\multispan{##1}##3}%
\let\\\cr
\setbox\tw@=\vbox{%
\ialign{&##\unskip\hfil\cr\BODY\crcr}%
\get@widths{#3}%
}%
\endgroup
\begin{tabular}[#1]{#2}\BODY\end{tabular}}
\def\get@widths#1{%
\def\@temp{\else\@latex@warning{No such column}\fi}
\setbox\z@=\lastbox
\get@next@width
\xdef#1##1{%
\noexpand\ifcase##1\relax\unexpanded\expandafter{\@temp}%
}%
}
\def\get@next@width{%
\setbox\z@=\hbox{\unhbox\z@\unskip\global\setbox\@ne=\lastbox}%
\ifvoid\@ne
\else
\edef\@temp{\noexpand\or\the\wd\@ne\unexpanded\expandafter{\@temp}}%
\expandafter\get@next@width
\fi
}
\makeatother
\begin{document}
\begin{mtabular}{lcr}{\foo}
abc & def & ghi \\
ABC & \multicolumn{2}{c}{aaa} \\
1 & 12 & 123
\end{mtabular}
The width of the first column was \foo{1}
The width of the second column was \foo{2}
The width of the third column was \foo{3}
\end{document}
It works by first typesetting the table in a “reduced” form, then taking off its last row and dismantling it bit by bit. The last argument to mtabular is a macro name that can later be used with a numeric argument for getting the relative column width.
