SQL、Firebird、基于其他表的动态联合
我需要你的帮助。我需要构建一个动态联合SQL语句。 (或存储过程) 在表A1中有为我的SQL参数存储的值。 例如:SQL、Firebird、基于其他表的动态联合,sql,sql-server,union,firebird,unpivot,Sql,Sql Server,Union,Firebird,Unpivot,我需要你的帮助。我需要构建一个动态联合SQL语句。 (或存储过程) 在表A1中有为我的SQL参数存储的值。 例如: ID | Name 1 | 16 2 | 23 3 | 30 在表B1中存储了所有其他值。但表1中的每一行我都需要一个工会 例如: 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 =
ID | Name
1 | 16
2 | 23
3 | 30
在表B1中存储了所有其他值。但表1中的每一行我都需要一个工会
例如:
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是动态的,所以不可能生成静态联合sql。请帮帮我。我可以用:cte with做这个吗
致意
射频
第二种解释:
我会尽量使我的解释更容易理解。对不起,我的第一个问题。我看这是不对的
由于TableB1的表设计,我需要一个动态联合(或其他东西)。以水平方式存储每个月/年的值
示例表B1:
date | xxxx | ID1 | ID2 | ID3 | ID4 ...
2014-07 | n | 20 | 30 | 40 |
2014-08 | n | 40 | 50 | 70 |
日期| 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
表B1.date |表A1.ID |表A1.Name |表B1.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语法以获得正确的列
也许我必须先做一个unpivot存储过程。您知道我如何在Firebird中实现这一点吗?我不确定表B1中的字段xxxx代表什么,但我假设您在表B1中没有ID字段,并且对于表A1中的每个ID,您需要表B1中相应的IDx字段。我还假设您的ID字段是数字,名称是数字。 下面是EXECUTE块内的示例代码,但可以轻松地放入存储过程中。使用execute块的原因是,例如,如果通过ADO执行,它会变得灵活 我进一步阐述了Frazz所说的重组表格B1的想法 您将需要以下临时表
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
您能提供一些预期输出的示例吗?为什么你不能这么做:
Select b.*from TableB1 b join TableA1 a on a.ID=b.ID
?阅读你的查询和你的问题,我看到的是你正在为联合选择TableB1的内容,而没有对TableA1做任何事情。还需要注意的是:为什么不避免联合并使用?这是Firebird还是SQL Server?为什么两个标签都有?@Frazz:因为安装Firebird或MSSQL数据库时可以使用该软件。这两个数据库都受支持—TableB1的结构显然是问题所在。您希望使用TableA1的ID从TableB1中选择一列。您不能将TableB1重新构造为每个日期和ID有一行,再加上一列值吗?这将是查询和维护的最佳解决方案。否则,您将需要复杂的CASE语句或存储过程。但当您在表A1中添加新ID(以及在表B1中添加新列)时,两者都不够灵活,无法自行调整。