2014-09-13 56 views
1

我有一個生成星期五和星期四的firebird程序。我用下面的查詢生成數據列表:需要SQL 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

Derek,

在我的工作中,我們遇到了類似的情況。我們的代碼正在從客戶端執行,因此我們最終創建了一個返回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,然後您可以執行該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) 

我幾件事情我想指出的.. 的是,我不能讓列標題來完全按照你想要的。 此示例僅適用於星期四字段,您需要更改代碼以處理星期五字段。 我假設你可能有相同的日期,促銷和課程的倍數,所以我總結助手存儲過程中的註冊字段。我希望這有助於,