Я думаю, что union all
это путь. Я бы сделал:
select productName, sum(input) as input_qty, sum(output) as output_qty
from ((select productName, qty as input, null as output
from input
) union all
(select productName, null, qty
from output
)
) io
group by productName;
Обратите внимание, что productName
появляется только один раз в наборе результатов. Я не вижу смысла включать его дважды. Если нет строки output
(или нет input
), то соответствующий qty
будет NULL
.
Я использую следующие подходы:
Вариант на последнем делает исключение членом класса броска. Я раньше делал это, но нашел это громоздким.
Я склонен помещать Исключения один на файл в том же пакете как объекты, которые производят их в отдельных файлах. Это - парадигма, используемая API Java и библиотеками .NET, таким образом, большинство людей, по крайней мере, знакомо с организацией объектов в той точке.
Современный IDE делает достаточно хорошее задание отслеживания файлов в каталоге, за которым ухаживают преимущества наличия класса в файле того же имени, перевешивают значение наличия меньшего количества файлов.
В C++ я всегда определял классы, которые я буду использовать в качестве исключений в том же пространстве имен как классы, которые бросают их, соразмещая их в том же заголовке. Для исключений общего назначения, которые будут совместно использованы классами, я использую единственный заголовок для собирания в группу их, наряду с другими служебными функциями и классами.
Я не полагаю, что существует любой корректный способ сделать вещи в этом отношении; это - любые работы для Вас в Вашем контексте.