希望有人可以通过2个查询的UNION帮助MariaDB 10.3中的初学者。
以下每个查询都可以很好地工作,但是当我要将结果合并为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秒)才能产生其输出)
谢谢
答案 0 :(得分:0)
问题可能是您的单个查询未处理整个结果集。因此,他们返回的行之前到达有问题的行。
在任何情况下,使用$arr = json_decode($GameState, true);
if(array_key_exists('message', $arr)){
if($arr['message'] != 'no game for given game_id'){
echo "<h2> The Server is up and running </h2>";
}else{
echo "<h2> The Server is currently turned off </h2>";
}
}
都很容易避免被零除。因此,无论您在何处进行分割,都可以使用它。例如:
nullif()