SQL,Firebird,动态联盟基于其他表

时间:2014-08-18 14:42:12

标签: sql sql-server union firebird unpivot

我需要你的帮助。我需要构建一个动态联合SQL语句。 (或存储过程)

TableA1 中,存储了我的SQL参数的值。 例如:

ID | Name
1 | 16
2 | 23
3 | 30

TableB1 中,存储了所有其他值。但我需要TableA1中的每一行都是一个联合

例如:

Select b.* from TableB1 b
join TableA1 a on a.ID = b.ID
where b.ID = 1
union
Select b.* from TableB1
join TableA1 a on a.ID = b.ID
where b.ID = 2

因为TableA1是动态的,所以不可能创建一个静态的union-sql。请帮我。我可以这样做:cte WITH?

祝你好运 射频

第二个解释: 我会尽力使我的解释更容易理解。对不起我的第一个问题。我觉得这不对。

由于TableB1的表设计,我需要一个动态联合(或其他东西)。每个月/年以水平方式存储的值。

示例 TableB1

date    | xxxx | ID1 |  ID2 | ID3 | ID4 ...
2014-07 | n    |  20 |   30 |  40 |
2014-08 | n    |  40 |   50 |  70 |

输出应如下所示:

TableB1.date | TableA1.ID | TableA1.Name | TableB1.ID x |
2014-07      |          1 |         16   |    20    
2014-08      |          1 |         16   |    40
2014-07      |          2 |         23   |    30      
2014-08      |          2 |         23   |    50
2014-07      |          3 |         30   |    40      
2014-08      |          3 |         30   |    70

我以为我会将sql放入存储过程,因为对于每个联合,我必须更改SQL语法以获得正确的列。

也许我必须首先制作一个非存储过程。你知道我怎么能在Firebird中做到这一点吗?

1 个答案:

答案 0 :(得分:1)

我不确定TableB1中的字段xxxx是什么,但我假设您在TableB1中没有ID字段,并且对于TableA1中的每个ID,您需要TableB1中的相应IDx字段。我还假设您的ID字段是数字,名称是数字。 这是EXECUTE BLOCK中的示例代码,但可以很容易地放入STORED PROCEDURE。执行块的原因是,例如,如果通过ADO执行,则使其变得灵活。

我扩展了Frazz说重组TableB1的想法。

您将需要以下临时表

CREATE GLOBAL TEMPORARY TABLE GTT_TEMP (
    DT   VARCHAR(10),
    ID   INTEGER,
    VAL  INTEGER
) ON COMMIT DELETE ROWS;

这是SQL

EXECUTE BLOCK
returns (TableB1_DATE VARCHAR(10),
         TableA1_ID INTEGER,
         tableA1_Name INTEGER,
         tableB1_ID INTEGER )
as
declare variable sql varchar(1000);
declare variable id integer;
begin

    for
    Select TABLEA1.ID FROM TABLEA1
    INTO :id
    do
    begin
       sql = 'INSERT INTO GTT_TEMP ( DT, ID, VAL ) SELECT tableb1."DATE", '||:id||', ID'||:id||' from tableb1 WHERE tableb1.ID'||:id||' > 0' ;
       EXECUTE Statement :sql;
    end

    FOR 
    Select GTT_TEMP.DT, GTT_TEMP.ID, tablea1.NAME, GTT_TEMP.VAL from GTT_TEMP, TABLEA1 WHERE tablea1.ID = gtt_temp.ID
    INTO :TableB1_DATE,
         :TableA1_ID,
         :TableA1_NAME,
         :TableB1_ID
     DO
     BEGIN
        suspend;
     END

END