#mysql #sql #sql-server
#mysql #sql #sql-сервер
Вопрос:
Мне нужно перевести этот запрос, который работает на SQL Server, в MySQL. Я обошел его не менее 50 раз, и я в тупике и даже не могу найти отправную точку.
Проблемы в двух словах:
- Он имеет не одно, а два
FULL OUTER
объединения, которые MySQL не выполняет. Я знаю, что это можно как-то эмулировать, используяUNION
в сочетании сLEFT
иRIGHT
joins . - Он объединяет таблицы на нескольких условиях, и я не уверен, как добавить критерии исключения в
ON
if, выполняя типичныйRIGHT JOIN
SELECT COALESCE(ca.reporting_period, s_p.reporting_period, s_uy.reporting_period) AS reporting_period,
COALESCE(ca.state, s_p.state, s_uy.state) AS state,
COALESCE(ca.servicer, s_p.servicer, s_uy.servicer) AS servicer,
COALESCE(ca.product, s_p.product, s_uy.product) AS product,
COALESCE(ca.product_group, s_p.product_group, s_uy.product_group) AS product_group,
COALESCE(ca.portfolio, s_p.portfolio, s_uy.portfolio) AS portfolio,
COALESCE(ca.channel, s_p.channel, s_uy.channel) AS channel,
ca.Gross,
ca.Costs,
ca.commission,
ca.commissionable,
s_p.WAVG_placed_numerator,
s_p.place_balance AS WAVG_placed_denominator,
SUM(s_uy.cum_gross) AS gross_uy_num,
SUM(s_uy.cum_netnet) AS netnet_uy_num,
SUM(s_uy.cum_commission) AS servicer_uy_num,
SUM(s_uy.num_accounts) AS uy_den,
ca.costs_recovered
# INTO adhoc_work.RevenueReport_Legal
FROM adhoc_work.Cash ca
FULL OUTER JOIN adhoc_work.Summary_placed s_p
ON ca.reporting_period = s_p.reporting_period
AND ca.state = s_p.state
AND ca.servicer = s_p.servicer
AND ca.product = s_p.product
AND ca.product_group = s_p.product_group
AND ca.portfolio = s_p.portfolio
AND ca.channel = s_p.channel
FULL OUTER JOIN adhoc_work.Summary_uy s_uy
ON ca.reporting_period = s_uy.reporting_period
AND ca.state = s_uy.state
AND s_p.state = s_uy.state
AND ca.servicer = s_uy.servicer
AND s_p.servicer = s_uy.servicer
AND ca.product = s_uy.product
AND s_p.product = s_uy.product
AND ca.product_group = s_uy.product_group
AND s_p.product_group = s_uy.product_group
AND ca.portfolio = s_uy.portfolio
AND s_p.portfolio = s_uy.portfolio
AND ca.channel = s_uy.channel
AND s_p.channel = s_uy.channel
WHERE COALESCE(ca.reporting_period,s_p.reporting_period,s_uy.reporting_period) BETWEEN DATE_FORMAT(TIMESTAMPADD(MONTH,-13,NOW(3)),'%Y%m%d') AND DATE_FORMAT(NOW(3),'%Y%m%d')
GROUP BY COALESCE(ca.reporting_period,s_p.reporting_period,s_uy.reporting_period)
,COALESCE(ca.state,s_p.state,s_uy.state)
,COALESCE(ca.servicer,s_p.servicer,s_uy.servicer)
,COALESCE(ca.product,s_p.product,s_uy.product)
,COALESCE(ca.product_group,s_p.product_group,s_uy.product_group)
,COALESCE(ca.portfolio,s_p.portfolio,s_uy.portfolio)
,COALESCE(ca.channel,s_p.channel,s_uy.channel)
,ca.gross
,ca.Costs
,ca.commission
,ca.commissionable
,s_p.WAVG_placed_numerator
,s_p.place_balance
,ca.costs_recovered;
Ответ №1:
На самом деле, ваш запрос не совсем выполняет полное внешнее соединение, потому что условие, подобное этому:
ca.state = s_uy.state
требуется ca.state
сопоставление. То есть внешнее соединение превращается во внутреннее соединение.
Итак, чтобы ответить на ваш вопрос более теоретически, самый простой метод, вероятно, состоит в том, чтобы сгенерировать все строки, используя UNION
среди таблицы, а затем использовать left join
:
FROM (SELECT reporting_period, . . .
FROM adhoc_work.Cash ca
UNION -- on purpose to remove duplicates
SELECT reporting_period, . . .
FROM adhoc_work.Summary_placed
UNION -- on purpose to remove duplicates
SELECT reporting_period, . . .
FROM adhoc_work.Summary_uy
) x LEFT JOIN
adhoc_work.Cash ca
ON x.reporting_period = ca.reporting_period AND
. . . LEFT JOIN
adhoc_work.Summary_placed s_p
ON x.reporting_period = s_p.reporting_period AND
. . . LEFT JOIN
adhoc_work.Summary_uy s_uy
ON x.reporting_period = s_uy.reporting_period AND
. . .
Комментарии:
1. Я пытался пойти по предложенному вами пути. Одно из препятствий заключается в том, что предлагаемые
UNION
вами правила требуют, чтобы все поля вUNION
разделах были идентичными. Как вы можете видеть в исходном запросе, первые пять или около того полей одинаковы, но после этого они расходятся. И 1 к вашему замечанию , что исходный запрос на самом деле не является aFULL OUTER JOIN
. Я начал экспериментировать с тем, чтобы просто сделать ихLEFT JOIN
s, и я получаю правильный, но другой ответ, в котором мой MySQL является почти полным подмножеством ответа SQL Server. Вот где я сейчас нахожусь. Я в этом над головой.