我有一个程序,在firebird中生成星期五和星期四的日期。我使用以下查询生成数据列表:
select w_start as "Friday", w_end as "Thursday",
(select count(*) from course C
inner join enrolment E on E.cod_course=C.id
where E.date_enrolled between w_start and w_end
and C_TYPE = 'PU' and CONFIRMED='C'
and (C.name like :PublicCourseOption1 or C.name like :PublicCourseOption2 or C.name like :PublicCourseOption3 or C.name like :PublicCourseOption4
or C.VERSION like :CourseVersion1 or C.version like :CourseVersion2 or C.version like :CourseVersion3 )
) as "Enrolments",
(select list(distinct promotype, ', ') from programmers where datesent between w_start and w_end) as "Promos",
(select list(distinct course, ', ') from programmers where datesent between w_start and w_end) as "Courses"
from get_weeks(:dtFromDate, :dtToDate) wks
order by w_start
它会产生以下结果:
Friday Thursday Enrolments Promos Courses
04/01/2013 10/01/2013 5 FAX WHS
11/01/2013 17/01/2013 11 EMAIL WHS
18/01/2013 24/01/2013 6 FAX WHS
25/01/2013 31/01/2013 12 EMAIL, FAX RTW, YSM103
01/02/2013 07/02/2013 17 EMAIL, FAX, Wcover REF-CIT, WHS Toll, WorkCover
08/02/2013 14/02/2013 19 FAX HSR HUR- INFO
15/02/2013 21/02/2013 12 FAX MC
22/02/2013 28/02/2013 19 EMAIL, FAX ARTW, DYS25, MC
01/03/2013 07/03/2013 22 COMCARE, FAX, Wcover COMCARE, COMM, WorkCover
08/03/2013 14/03/2013 13 FAX HSR
15/03/2013 21/03/2013 12
22/03/2013 28/03/2013 16 FAX HSR
有谁知道如何将数据转换为数据透视表,如下所示:
Promos- Course - 10/01/2013 (Thursday Date) - 17/01/2013 (Thursday Date)
FAX - WHS - 15 enrolments - 25 enrolments
EMAIL - MC - 14 Enrolments - 36 enrolments
日期是动态创建的,并且每次运行查询时都会有所不同,因此静态查询无法满足我的需求。
答案 0 :(得分:0)
德里克,
在我的工作中,我们遇到了类似的情况。我们的代码是从客户端执行的,所以我们最终做的是创建一个返回SQL语句的存储过程,然后我们执行返回的sql语句。
为了完成你的任务,我创建了一个名为X_GET_ENROLLMENTS_FOR_DATE的助手存储过程
CREATE OR ALTER PROCEDURE X_GET_ENROLLMENTS_FOR_DATE (
PROMOS VARCHAR(100),
COURSES VARCHAR(100),
DATE_STRING VARCHAR(30))
RETURNS (
ENROLLMENTS INTEGER)
AS
BEGIN
SELECT SUM(ENROLLMENTS)
FROM TABLE_X
WHERE TABLE_X.PROMOS = :PROMOS
AND TABLE_X.COURSES = :COURSES
AND TABLE_X.THURSDAY = :DATE_STRING
INTO ENROLLMENTS;
SUSPEND;
END
我使用EXECUTE BLOCK创建了以下内容,但可以很容易地放在另一个存储过程中。
EXECUTE BLOCK
RETURNS (
SQL VARCHAR(3000))
AS
DECLARE VARIABLE SELECT_SQL VARCHAR(2000);
DECLARE VARIABLE WHERE_SQL VARCHAR(2000);
DECLARE VARIABLE PROMOS VARCHAR(30);
DECLARE VARIABLE COURSES VARCHAR(30);
DECLARE VARIABLE THURSDAY VARCHAR(30);
DECLARE VARIABLE ENROLLMENTS INTEGER;
DECLARE VARIABLE FIELD_ID INTEGER; --DECLARE VARIABLE S varchar(1000)
DECLARE VARIABLE FIELD_COUNT INTEGER;
BEGIN
SELECT_SQL = 'SELECT distinct promos, courses ,' || ASCII_CHAR(13);
WHERE_SQL = 'FROM table_x' || ASCII_CHAR(13);
FIELD_ID = 0;
SELECT COUNT(DISTINCT THURSDAY)
FROM TABLE_X
INTO :FIELD_COUNT;
FOR
SELECT DISTINCT THURSDAY
FROM TABLE_X
INTO :THURSDAY
DO
BEGIN
FIELD_ID = :FIELD_ID + 1;
IF (:FIELD_ID = :FIELD_COUNT) THEN
SELECT_SQL = :SELECT_SQL || 'T' || :FIELD_ID || '.Enrollments ' || 'Thu_' || REPLACE(:THURSDAY, '/', '_') || ASCII_CHAR(13);
ELSE
SELECT_SQL = :SELECT_SQL || 'T' || :FIELD_ID || '.Enrollments ' || 'Thu_' || REPLACE(:THURSDAY, '/', '_') || ',' || ASCII_CHAR(13);
WHERE_SQL = :WHERE_SQL || 'LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, ''' || :THURSDAY || ''') T' || :FIELD_ID || ' on (1 = 1)' || ASCII_CHAR(13);
-- WHERE_SQL = :WHERE_SQL || 'INNER JOIN ( Select Sum(Enrollments) Enrollments from table_x where promos = ''' || :PROMOS || ''' and Courses = ''' || :COURSES || ''' and thursday = ''' || :THURSDAY || ''') T' || :FIELD_ID || ' on (1 = 1)' || ASCII_CHAR(13);
END
SQL = :SELECT_SQL || :WHERE_SQL;
SUSPEND;
END;
执行存储过程时,它将返回以下SQL,然后您可以执行该步骤。
SELECT distinct promos, courses ,
T1.Enrollments Thu_07_02_2013,
T2.Enrollments Thu_07_03_2013,
T3.Enrollments Thu_10_01_2013,
T4.Enrollments Thu_14_02_2013,
T5.Enrollments Thu_14_03_2013,
T6.Enrollments Thu_17_01_2013,
T7.Enrollments Thu_21_02_2013,
T8.Enrollments Thu_21_03_2013,
T9.Enrollments Thu_24_01_2013,
T10.Enrollments Thu_28_02_2013,
T11.Enrollments Thu_28_03_2013,
T12.Enrollments Thu_31_01_2013
FROM table_x
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '07/02/2013') T1 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '07/03/2013') T2 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '10/01/2013') T3 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '14/02/2013') T4 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '14/03/2013') T5 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '17/01/2013') T6 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '21/02/2013') T7 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '21/03/2013') T8 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '24/01/2013') T9 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '28/02/2013') T10 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '28/03/2013') T11 on (1 = 1)
LEFT OUTER JOIN X_GET_ENROLLMENTS_FOR_DATE ( table_x.PROMOS,table_x.COURSES, '31/01/2013') T12 on (1 = 1)
我想指出的一些事情...... 是我无法让列标题完全按照您的意愿来。 此示例仅适用于星期四字段,您需要更改代码以处理星期五字段。 我假设你可能有相同的日期,促销和课程的倍数,所以我在助手存储过程中总结了注册字段。
我希望这有帮助,