我需要你的帮助。我需要构建一个动态联合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中做到这一点吗?
答案 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