Каждый UNION SELECT работает нормально, но выдает ошибку UNION - PullRequest
0 голосов
/ 05 февраля 2019

Надеясь, что кто-то может помочь новичку в MariaDB 10.3 с UNION из 2 запросов.

Каждый из приведенных ниже запросов прекрасно работает на себя, но когда я хочу объединить результаты в UNION, он выдает «Деление на 0 'предупреждений.

SQL 1:

    WITH hv_sub AS (SELECT hv.portfolio,
                                    hv.price_date,
                                    SUM(hv.VALUE) AS curValue,
                                    SUM(hv.VALUE) + IFNULL(SUM(tv.cashflow),0) AS netValue,
                                    SUM(hv.retrn) AS portfolio_retrn
                            FROM holdings_VIEW_day_by_day hv
                                LEFT JOIN transactions_VIEW tv ON tv.tr_date = hv.price_date AND hv.portfolio = tv.portfolio AND hv.isin = tv.isin
                            WHERE hv.isin <> 'EU0000000000'
                            GROUP BY hv.portfolio, hv.price_date
                            ORDER BY hv.price_date),

            portfolio_retrn_pct AS (SELECT hv_sub.portfolio,
                                                        hv_sub.price_date,
                                                        hv_sub.portfolio_retrn,
                                                        hv_sub.netValue / LAG(hv_sub.curValue,1) OVER (PARTITION BY hv_sub.portfolio ORDER BY hv_sub.price_date) AS portfolio_retrn_pct
                                                FROM hv_sub)

    SELECT prp.portfolio,
                'Portfolio',
                CAST(YEAR(prp.price_date) AS CHAR) AS yr,
                CONCAT(ROUND(100*(EXP(SUM(LN(prp.portfolio_retrn_pct)))-1),1),"%") AS portfolio_twRoR,
                SUM(prp.portfolio_retrn) AS portfolio_retrn,
                0 AS yrEndValue
        FROM portfolio_retrn_pct prp
        GROUP BY prp.portfolio, YEAR(prp.price_date)

SQL 2:

WITH maxDates AS (SELECT hv.portfolio,
                                    hv.isin,
                                    YEAR(hv.price_date) as yr,
                                    MAX(hv.price_date) as maxDate
                            FROM holdings_VIEW_day_by_day hv
                            GROUP BY YEAR(hv.price_date), hv.portfolio, hv.isin),
        yrEndValues AS (SELECT md.*, hv.value
                                FROM holdings_VIEW_day_by_day hv
                                JOIN maxDates md ON md.portfolio = hv.portfolio AND md.isin = hv.isin AND md.maxDate = hv.price_date
                                GROUP BY hv.portfolio, hv.isin, YEAR(hv.price_date)
                                ORDER BY YEAR(hv.price_date), hv.stock_name)

SELECT hv.portfolio,
            hv.stock_name,
            CAST(YEAR(hv.price_date) AS CHAR) as yr,
            CONCAT(ROUND(100*(EXP(SUM(LN(hv.retrn_pct)))-1),1),"%") AS twRoR,
            ROUND(SUM(hv.retrn),0) AS retrn,
            ROUND(yEV.value,0) AS yrEndValue
    FROM holdings_VIEW_day_by_day hv
    LEFT JOIN yrEndValues yEV ON hv.portfolio = yEV.portfolio AND hv.isin = yEV.isin AND YEAR(hv.price_date) = yEV.yr
    GROUP BY hv.portfolio, hv.stock_name, YEAR(hv.price_date)
    ORDER BY YEAR(hv.price_date), hv.portfolio, hv.stock_name, EXP(SUM(LN(hv.retrn_pct))) DESC

UNION SQL:

WITH maxDates AS (SELECT hv1.portfolio,
                                    hv1.isin,
                                    YEAR(hv1.price_date) as yr,
                                    MAX(hv1.price_date) as maxDate
                            FROM holdings_VIEW_day_by_day hv1
                            GROUP BY YEAR(hv1.price_date), hv1.portfolio, hv1.isin),

        yrEndValues AS (SELECT md.*, hv.value
                                FROM holdings_VIEW_day_by_day hv
                                JOIN maxDates md ON md.portfolio = hv.portfolio AND md.isin = hv.isin AND md.maxDate = hv.price_date
                                GROUP BY hv.portfolio, hv.isin, YEAR(hv.price_date)
                                ORDER BY YEAR(hv.price_date), hv.stock_name),

        hv_sub AS (SELECT hv2.portfolio,
                                hv2.price_date,
                                SUM(hv2.VALUE) AS curValue,
                                SUM(hv2.VALUE) + IFNULL(SUM(tv.cashflow),0) AS netValue,
                                SUM(hv2.retrn) AS portfolio_retrn
                        FROM holdings_VIEW_day_by_day hv2
                            LEFT JOIN transactions_VIEW tv ON tv.tr_date = hv2.price_date AND hv2.portfolio = tv.portfolio AND hv2.isin = tv.isin
                        WHERE hv2.isin <> 'EU0000000000'
                        GROUP BY hv2.portfolio, hv2.price_date
                        ORDER BY hv2.price_date),

        portfolio_retrn_pct AS (SELECT hv_sub.portfolio,
                                                    hv_sub.price_date,
                                                    hv_sub.portfolio_retrn,
                                                    hv_sub.netValue / LAG(hv_sub.curValue,1) OVER (PARTITION BY hv_sub.portfolio ORDER BY hv_sub.price_date) AS portfolio_retrn_pct
                                            FROM hv_sub)


(SELECT hv.portfolio,
            hv.stock_name,
            CAST(YEAR(hv.price_date) AS CHAR) as yr,
            CONCAT(ROUND(100*(EXP(SUM(LN(hv.retrn_pct)))-1),1),"%") AS twRoR,
            ROUND(SUM(hv.retrn),0) AS retrn,
            ROUND(yEV.value,0) AS yrEndValue
    FROM holdings_VIEW_day_by_day hv
        LEFT JOIN yrEndValues yEV ON hv.portfolio = yEV.portfolio AND hv.isin = yEV.isin AND YEAR(hv.price_date) = yEV.yr
    GROUP BY hv.portfolio, hv.stock_name, YEAR(hv.price_date)
    ORDER BY YEAR(hv.price_date), hv.portfolio, hv.stock_name, EXP(SUM(LN(hv.retrn_pct))) DESC)

UNION

(SELECT prp.portfolio,
            '_Portfolio',
            CAST(YEAR(prp.price_date) AS CHAR) AS yr,
            CONCAT(ROUND(100*(EXP(SUM(LN(prp.portfolio_retrn_pct)))-1),1),"%") AS portfolio_twRoR,
            SUM(prp.portfolio_retrn) AS portfolio_retrn,
            0
    FROM portfolio_retrn_pct prp
    GROUP BY prp.portfolio, YEAR(prp.price_date))

ORDER BY yr, stock_name;

Может ли кто-нибудь указать мне правильное направление?

ДАЛЬНЕЙШИЙ НАЙДЕН: Предупреждения исчезают, как только яудалите глобальный UNION SORT BY в конце.

(я также рад использовать любые способы для оптимизации этих запросов ... это не выглядит элегантно и занимает довольно много времени (15 сек)для производства своей продукции)

Спасибо

1 Ответ

0 голосов
/ 05 февраля 2019

Возможно, проблема в том, что ваши отдельные запросы не обрабатывают весь набор результатов.Таким образом, они возвращают строки до того, как попадут в проблемную строку.

В любом случае деление на ноль легко избежать, используя nullif().Поэтому, где бы у вас ни было разделение, используйте его.Например:

(hv_sub.netValue / 
 NULLIF(LAG(hv_sub.curValue, 1) OVER (PARTITION BY hv_sub.portfolio ORDER BY hv_sub.price_date), 0)
) AS portfolio_retrn_pct
...