Мое решение поставляется в двух вариантах.Какой из них лучше подходит вам, может зависеть от того, какой из них даст лучший план выполнения при проверке ваших данных.
Описание варианта # 1 : (В обоих случаях я описываю только логикуза основным подвыбором SELECT LEFT JOIN фактически заменяется часть, но сценарии идут как полные запросы, эквивалентные вашим:
- Извлечение и объединение всех элементов из обеих таблиц
tools
. - Соединить список с таблицей
marks
соответственно. - Группировать набор результатов по элементам инструмента и получить значения.
Запрос:
SELECT *
FROM ES_TOOL
INNER JOIN ES_HARDWARE ON ES_HARDWARE.eshw_ID = ES_TOOL.ESTOOL_HARDWARE
INNER JOIN ES_PAYMENT on ES_payment.espay_id = es_TOOL.estool_payment
LEFT JOIN (
SELECT
tools.tool,
COUNT(*) AS AmtMarks
FROM (
SELECT 'tchap' AS tbl, estch_id AS id, estch_tool AS tool
FROM ES_TOOL_CHAPTER
UNION ALL
SELECT 'tfacet' AS tbl, estfa_id AS id, estfa_tool AS tool
FROM ES_TOOL_FACET
) tools
INNER JOIN ES_MARK marks
ON tools.tbl = 'tchap' AND tools.id = marks.esmark_tool_chapter
OR tools.tbl = 'tfacet' AND tools.id = marks.esmark_tool_facet
GROUP BY tools.tool
) h ON ES_TOOL.estool_id = h.tool
Вариант # 2 :
- Соедините
ES_TOOL_CHAPTER
против marks
и получите все значения estch_tool
, включая дубликаты. - Аналогично, объедините
ES_TOOL_FACET
против marks
и получите все значения estfa_tool
, включая дубликаты. - UNION ALL обоих наборов.
- Группируйте полученный набор по инструментам иполучить счет.
И запрос:
SELECT *
FROM ES_TOOL
INNER JOIN ES_HARDWARE ON ES_HARDWARE.eshw_ID = ES_TOOL.ESTOOL_HARDWARE
INNER JOIN ES_PAYMENT on ES_payment.espay_id = es_TOOL.estool_payment
LEFT JOIN (
SELECT
tools.tool,
COUNT(*) AS AmtMarks
FROM (
SELECT estch_tool AS tool
FROM ES_TOOL_CHAPTER tools
INNER JOIN ES_MARK marks ON tools.estch_id = marks.esmark_tool_chapter
UNION ALL
SELECT estfa_tool AS tool
FROM ES_TOOL_FACET tools
INNER JOIN ES_MARK marks ON tools.estfa_id = marks.esmark_tool_facet
) tools
GROUP BY tools.tool
) h ON ES_TOOL.estool_id = h.tool