1.场景声明:在用报表工具开发报表时,由于数据查询结果依赖数据库中现有的数据,当筛选条件在数据库中无命中记录时查询结果往往是空的,这本符合条件,但有时用户又希望看到筛选条件全覆盖的查询结果,为此,sql语句必须根据查询结果动态伸缩,以达到预期的效果
2.实现思路:由于这种复杂的数据结果往往无法将查询的sql语句写死,需要动态构建sql语句,所以考虑用存储过程实现,存储过程只传入参的筛选条件,存储过程根据一定的规则while循环将需要的点补全后作为表A,将条件查询结果集作为表B,通过B right join A实现补点效果
3.表B查询sql及查询结果:
SELECT REPLACE
( h.日期, ":00", "h" ) AS 日期,
round( REPLACE ( format( h.上限值, 2 ), ',', '' ), 2 ) AS 上限值
FROM
(
SELECT
concat( substr( g.日期, 6, 6 ), "(", g.时刻, ")" ) AS 日期,
( g.统调负荷 + g.东送负荷 - ( g.火电检修容量 - g.自备检修容量 ) * 0.5 * 0.9 - g.自备检修容量 * 0.85 * 0.9 ) AS 上限值
FROM
(
SELECT
e.日期,
e.时刻,
e.统调负荷,
e.东送负荷,
f.自备检修容量,
f.火电检修容量
FROM
(
SELECT
a.日期,
a.时刻,
a.预测值 AS 统调负荷,
b.预测值 AS 东送负荷
FROM
(
SELECT
( @ROW := @ROW + 1 ) AS 序号,
businessTime AS 时刻,
businessDate AS 日期,
planValue AS 预测值
FROM
( SELECT @ROW := 0 ) t,
next_nified_dispatch_load_forecast
WHERE
businessDate >= '2022-06-07'
AND businessDate <= '2022-06-17'
GROUP BY
businessDate,
businessTime
ORDER BY
( @ROW := @ROW + 1 )
) a
INNER JOIN (
SELECT
( @ROW := @ROW + 1 ) AS 序号,
businessTime AS 时刻,
businessDate AS 日期,
planValue AS 预测值
FROM
( SELECT @ROW := 0 ) t,
next_eastward_ran_plan
WHERE
businessDate >= '2022-06-07'
AND businessDate <= '2022-06-17'
GROUP BY
businessDate,
businessTime
ORDER BY
( @ROW := @ROW + 1 )
) b ON a.日期 = b.日期
AND a.时刻 = b.时刻
ORDER BY
a.日期,
a.时刻
) e
LEFT JOIN (
SELECT
c.日期,
c.自备检修容量,
d.火电检修容量
FROM
(
SELECT
( @ROW := @ROW + 1 ) AS 序号,
( SELECT SUM( captive_capacity ) 自备总容量 FROM spot_base_data.t_node_capacity_common WHERE type = 1 ) - CAST( ROUND( SUM( capacity ), 3 ) AS DECIMAL ) 自备检修容量,
businessDate AS 日期
FROM
( SELECT @ROW := 0 ) t,
maintenance_information_import
WHERE
businessDate >= '2022-06-07'
AND businessDate <= '2022-06-17'
AND equipment = '机组'
AND equipmentDispatchingName REGEXP 'xx|yy'
GROUP BY
businessDate
ORDER BY
( @ROW := @ROW + 1 )
) c
INNER JOIN (
SELECT
( @ROW := @ROW + 1 ) AS 序号,
( SELECT SUM( power_installation_capacity ) + SUM( captive_capacity ) 装机总容量 FROM spot_base_data.t_node_capacity_common WHERE type = 1 ) - CAST( ROUND( SUM( capacity ), 3 ) AS DECIMAL ) 火电检修容量,
businessDate AS 日期
FROM
( SELECT @ROW := 0 ) t,
maintenance_information_import
WHERE
businessDate >= '2022-06-07'
AND businessDate <= '2022-06-17'
AND equipment = '机组'
GROUP BY
businessDate
ORDER BY
( @ROW := @ROW + 1 )
) d ON c.日期 = d.日期
) f ON f.日期 = e.日期
) g
) h
WHERE
日期 REGEXP '04:00|06:00|08:00|10:00|12:00|14:00|16:00|18:00|20:00|22:00|11:00|17:00|05:00'
查询结果:
日期 上限值
06-07(04h) 12776.67
06-07(05h) 12782.67
06-07(06h) 13387.67
06-07(08h) 14223.27
06-07(10h) 15172.57
06-07(11h) 15562.17
06-07(12h) 14907.97
06-07(14h) 14273.77
06-07(16h) 14591.17
06-07(17h) 15226.17
06-07(18h) 15200.47
06-07(20h) 15762.37
06-07(22h) 15800.77
06-08(04h)
06-08(05h)
06-08(06h)
06-08(08h)
06-08(10h)
06-08(11h)
06-08(12h)
06-08(14h)
06-08(16h)
06-08(17h)
06-08(18h)
06-08(20h)
06-08(22h)
06-09(04h) 13330.37
06-09(05h) 13403.77
06-09(06h) 13882.47
06-09(08h) 14784.47
06-09(10h) 15672.77
06-09(11h) 16096.77
06-09(12h) 15407.07
06-09(14h) 14846.77
06-09(16h) 15237.47
06-09(17h) 15840.17
06-09(18h) 15751.07
06-09(20h) 16016.47
06-09(22h) 15933.47
06-10(04h)
06-10(05h)
06-10(06h)
06-10(08h)
06-10(10h)
06-10(11h)
06-10(12h)
06-10(14h)
06-10(16h)
06-10(17h)
06-10(18h)
06-10(20h)
06-10(22h)
06-11(04h)
06-11(05h)
06-11(06h)
06-11(08h)
06-11(10h)
06-11(11h)
06-11(12h)
06-11(14h)
06-11(16h)
06-11(17h)
06-11(18h)
06-11(20h)
06-11(22h)
结果可见查询缺少06-12日到06-17日的数据
4.A需借助存储过程动态构建
drop procedure getrange;
CREATE PROCEDURE getrange ( IN began date, IN eds date)
BEGIN
declare sqlx text;
set @sqlx = '';
WHILE began <= eds
DO
SET @sqlx = concat( @sqlx,'select "', RIGHT ( began, 5 ), '(04h)', '" as date union ' );
SET @sqlx = concat( @sqlx,'select "', RIGHT ( began, 5 ), '(05h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(06h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(08h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(10h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(11h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(12h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(14h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(16h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(17h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(18h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(20h)', '" as date union ' );
if began = eds then
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(22h)" as date');
else
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(22h)', '" as date union ' );
end if;
SET began = adddate( began, 1 );
END WHILE;
PREPARE stmt FROM @sqlx;
EXECUTE stmt;
END;
调用和结果:
CALL getrange ('2022-06-07','2022-06-17' );
date
06-07(04h)
06-07(05h)
06-07(06h)
06-07(08h)
06-07(10h)
06-07(11h)
06-07(12h)
06-07(14h)
06-07(16h)
06-07(17h)
06-07(18h)
06-07(20h)
06-07(22h)
06-08(04h)
06-08(05h)
06-08(06h)
06-08(08h)
06-08(10h)
06-08(11h)
06-08(12h)
06-08(14h)
06-08(16h)
06-08(17h)
06-08(18h)
06-08(20h)
06-08(22h)
06-09(04h)
06-09(05h)
06-09(06h)
06-09(08h)
06-09(10h)
06-09(11h)
06-09(12h)
06-09(14h)
06-09(16h)
06-09(17h)
06-09(18h)
06-09(20h)
06-09(22h)
06-10(04h)
06-10(05h)
06-10(06h)
06-10(08h)
06-10(10h)
06-10(11h)
06-10(12h)
06-10(14h)
06-10(16h)
06-10(17h)
06-10(18h)
06-10(20h)
06-10(22h)
06-11(04h)
06-11(05h)
06-11(06h)
06-11(08h)
06-11(10h)
06-11(11h)
06-11(12h)
06-11(14h)
06-11(16h)
06-11(17h)
06-11(18h)
06-11(20h)
06-11(22h)
06-12(04h)
06-12(05h)
06-12(06h)
06-12(08h)
06-12(10h)
06-12(11h)
06-12(12h)
06-12(14h)
06-12(16h)
06-12(17h)
06-12(18h)
06-12(20h)
06-12(22h)
06-13(04h)
06-13(05h)
06-13(06h)
06-13(08h)
06-13(10h)
06-13(11h)
06-13(12h)
06-13(14h)
06-13(16h)
06-13(17h)
06-13(18h)
06-13(20h)
06-13(22h)
06-14(04h)
06-14(05h)
06-14(06h)
06-14(08h)
06-14(10h)
06-14(11h)
06-14(12h)
06-14(14h)
06-14(16h)
06-14(17h)
06-14(18h)
06-14(20h)
06-14(22h)
06-15(04h)
06-15(05h)
06-15(06h)
06-15(08h)
06-15(10h)
06-15(11h)
06-15(12h)
06-15(14h)
06-15(16h)
06-15(17h)
06-15(18h)
06-15(20h)
06-15(22h)
06-16(04h)
06-16(05h)
06-16(06h)
06-16(08h)
06-16(10h)
06-16(11h)
06-16(12h)
06-16(14h)
06-16(16h)
06-16(17h)
06-16(18h)
06-16(20h)
06-16(22h)
06-17(04h)
06-17(05h)
06-17(06h)
06-17(08h)
06-17(10h)
06-17(11h)
06-17(12h)
06-17(14h)
06-17(16h)
06-17(17h)
06-17(18h)
06-17(20h)
06-17(22h)
如此便可构建出表B
5.接下来对存储过程进行改造,将表A当作字符串放入存储过程,right join表B即可获取到预期结果
DROP PROCEDURE getrange3;
CREATE PROCEDURE getrange3 ( IN began date, IN eds date)
BEGIN
declare leftsql text;
declare sqlx text;
set @leftsql = '';
set @sqlx = '';
set @leftsql = concat(@leftsql,"select u.date as 日期,
i.上限值 from
(SELECT REPLACE
( h.日期, ':00', 'h' ) AS 日期,
round( REPLACE ( format( h.上限值, 2 ), ',', '' ), 2 ) AS 上限值
FROM
(
SELECT
concat( substr( g.日期, 6, 6 ), '(', g.时刻, ')' ) AS 日期,
( g.统调负荷 + g.东送负荷 - ( g.火电检修容量 - g.自备检修容量 ) * 0.5 * 0.9 - g.自备检修容量 * 0.85 * 0.9 ) AS 上限值
FROM
(
SELECT
e.日期,
e.时刻,
e.统调负荷,
e.东送负荷,
f.自备检修容量,
f.火电检修容量
FROM
(
SELECT
a.日期,
a.时刻,
a.预测值 AS 统调负荷,
b.预测值 AS 东送负荷
FROM
(
SELECT
( @ROW := @ROW + 1 ) AS 序号,
businessTime AS 时刻,
businessDate AS 日期,
planValue AS 预测值
FROM
( SELECT @ROW := 0 ) t,
next_nified_dispatch_load_forecast
WHERE
businessDate >= '",began,
"' AND businessDate <='", eds ,
"'GROUP BY
businessDate,
businessTime
ORDER BY
( @ROW := @ROW + 1 )
) a
INNER JOIN (
SELECT
( @ROW := @ROW + 1 ) AS 序号,
businessTime AS 时刻,
businessDate AS 日期,
planValue AS 预测值
FROM
( SELECT @ROW := 0 ) t,
next_eastward_ran_plan
WHERE
businessDate >= '",began,
"' AND businessDate <='", eds ,
"'GROUP BY
businessDate,
businessTime
ORDER BY
( @ROW := @ROW + 1 )
) b ON a.日期 = b.日期
AND a.时刻 = b.时刻
ORDER BY
a.日期,
a.时刻
) e
LEFT JOIN (
SELECT
c.日期,
c.自备检修容量,
d.火电检修容量
FROM
(
SELECT
( @ROW := @ROW + 1 ) AS 序号,
( SELECT SUM( captive_capacity ) 自备总容量 FROM spot_base_data.t_node_capacity_common WHERE type = 1 ) - CAST( ROUND( SUM( capacity ), 3 ) AS DECIMAL ) 自备检修容量,
businessDate AS 日期
FROM
( SELECT @ROW := 0 ) t,
maintenance_information_import
WHERE
businessDate >= '",began,
"' AND businessDate <='", eds ,
"' AND equipment = '机组'
AND equipmentDispatchingName REGEXP 'xx|yy'
GROUP BY
businessDate
ORDER BY
( @ROW := @ROW + 1 )
) c
INNER JOIN (
SELECT
( @ROW := @ROW + 1 ) AS 序号,
( SELECT SUM( power_installation_capacity ) + SUM( captive_capacity ) 装机总容量 FROM spot_base_data.t_node_capacity_common WHERE type = 1 ) - CAST( ROUND( SUM( capacity ), 3 ) AS DECIMAL ) 火电检修容量,
businessDate AS 日期
FROM
( SELECT @ROW := 0 ) t,
maintenance_information_import
WHERE
businessDate >= '",began,
"' AND businessDate <='", eds ,
"' AND equipment = '机组'
GROUP BY
businessDate
ORDER BY
( @ROW := @ROW + 1 )
) d ON c.日期 = d.日期
) f ON f.日期 = e.日期
) g
) h
WHERE
日期 REGEXP '04:00|06:00|08:00|10:00|12:00|14:00|16:00|18:00|20:00|22:00|11:00|17:00|05:00') i");
WHILE began <= eds
DO
SET @sqlx = concat( @sqlx,'select "', RIGHT ( began, 5 ), '(04h)', '" as date union ' );
SET @sqlx = concat( @sqlx,'select "', RIGHT ( began, 5 ), '(05h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(06h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(08h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(10h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(11h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(12h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(14h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(16h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(17h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(18h)', '" as date union ' );
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(20h)', '" as date union ' );
if began = eds then
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(22h)" as date');
else
SET @sqlx = concat( @sqlx, 'select "', RIGHT ( began, 5 ), '(22h)', '" as date union ' );
end if;
SET began = adddate( began, 1 );
END WHILE;
set @leftsql = concat(@leftsql,' right join (',@sqlx,') u on i.日期=u.date');
PREPARE stmt FROM @leftsql;
EXECUTE stmt;
END;
调用和查询结果:
CALL getrange3 ('2022-06-07','2022-06-17' );
结果:
日期 上限值
06-07(04h) 12776.67
06-07(05h) 12782.67
06-07(06h) 13387.67
06-07(08h) 14223.27
06-07(10h) 15172.57
06-07(11h) 15562.17
06-07(12h) 14907.97
06-07(14h) 14273.77
06-07(16h) 14591.17
06-07(17h) 15226.17
06-07(18h) 15200.47
06-07(20h) 15762.37
06-07(22h) 15800.77
06-08(04h)
06-08(05h)
06-08(06h)
06-08(08h)
06-08(10h)
06-08(11h)
06-08(12h)
06-08(14h)
06-08(16h)
06-08(17h)
06-08(18h)
06-08(20h)
06-08(22h)
06-09(04h) 13330.37
06-09(05h) 13403.77
06-09(06h) 13882.47
06-09(08h) 14784.47
06-09(10h) 15672.77
06-09(11h) 16096.77
06-09(12h) 15407.07
06-09(14h) 14846.77
06-09(16h) 15237.47
06-09(17h) 15840.17
06-09(18h) 15751.07
06-09(20h) 16016.47
06-09(22h) 15933.47
06-10(04h)
06-10(05h)
06-10(06h)
06-10(08h)
06-10(10h)
06-10(11h)
06-10(12h)
06-10(14h)
06-10(16h)
06-10(17h)
06-10(18h)
06-10(20h)
06-10(22h)
06-11(04h)
06-11(05h)
06-11(06h)
06-11(08h)
06-11(10h)
06-11(11h)
06-11(12h)
06-11(14h)
06-11(16h)
06-11(17h)
06-11(18h)
06-11(20h)
06-11(22h)
06-12(04h)
06-12(05h)
06-12(06h)
06-12(08h)
06-12(10h)
06-12(11h)
06-12(12h)
06-12(14h)
06-12(16h)
06-12(17h)
06-12(18h)
06-12(20h)
06-12(22h)
06-13(04h)
06-13(05h)
06-13(06h)
06-13(08h)
06-13(10h)
06-13(11h)
06-13(12h)
06-13(14h)
06-13(16h)
06-13(17h)
06-13(18h)
06-13(20h)
06-13(22h)
06-14(04h)
06-14(05h)
06-14(06h)
06-14(08h)
06-14(10h)
06-14(11h)
06-14(12h)
06-14(14h)
06-14(16h)
06-14(17h)
06-14(18h)
06-14(20h)
06-14(22h)
06-15(04h)
06-15(05h)
06-15(06h)
06-15(08h)
06-15(10h)
06-15(11h)
06-15(12h)
06-15(14h)
06-15(16h)
06-15(17h)
06-15(18h)
06-15(20h)
06-15(22h)
06-16(04h)
06-16(05h)
06-16(06h)
06-16(08h)
06-16(10h)
06-16(11h)
06-16(12h)
06-16(14h)
06-16(16h)
06-16(17h)
06-16(18h)
06-16(20h)
06-16(22h)
06-17(04h)
06-17(05h)
06-17(06h)
06-17(08h)
06-17(10h)
06-17(11h)
06-17(12h)
06-17(14h)
06-17(16h)
06-17(17h)
06-17(18h)
06-17(20h)
06-17(22h)
ok,我们完成了动态补点,完美收工!!!
TRANSLATE with x
English
Arabic | Hebrew | Polish |
Bulgarian | Hindi | Portuguese |
Catalan | Hmong Daw | Romanian |
Chinese Simplified | Hungarian | Russian |
Chinese Traditional | Indonesian | Slovak |
Czech | Italian | Slovenian |
Danish | Japanese | Spanish |
Dutch | Klingon | Swedish |
English | Korean | Thai |
Estonian | Latvian | Turkish |
Finnish | Lithuanian | Ukrainian |
French | Malay | Urdu |
German | Maltese | Vietnamese |
Greek | Norwegian | Welsh |
Haitian Creole | Persian | |
TRANSLATE with
COPY THE URL BELOW
Back
EMBED THE SNIPPET BELOW IN YOUR SITE
Enable collaborative features and customize widget: Bing Webmaster Portal
Back
- 添加到短语集
- 没有此单词集:世界语 → 中文(简体)...
- 创建新的单词集...
- 拷贝