0

好的,所以我们有一堆这样命名的表:

training_data_001
training_data_002
training_data_003
training_data_004
training_data_005

然后为了找到那些我们查看另一个表中的字段的字段,我们将其命名为 master.training_type。

无论如何,我想知道是否有人知道用这种数据进行基于奇怪表名的连接的方法。像这样的东西:

SELECT foo FROM master WHERE id = ? 
INNER JOIN training_data_${master.training_type}
ON foo.id = training_data_${master.training_type}.foo_id

我知道我可以在客户端执行此操作,但最好让数据库执行此操作。

另请注意:它是 SQL Server。

更新:我决定只在客户端做。总之谢谢大家。

谢谢!

-fREW

4

5 回答 5

2

您只能使用动态 SQL 读取 master.training_type 来构建一个字符串,然后使用EXEC (@stringvar)

于 2008-12-09T19:57:09.180 回答
1

分区视图是一种可能的方法。由于您只选择 foo 列,您真的只是通过 INNER JOIN 检查训练表中是否存在一行?此外,您似乎正在尝试在联接中使用 foo 作为别名,但在您的 SELECT 子句中没有以这种方式设置。结果,我在这里猜测您真正想要什么。

另一个问题......训练表集是静态的吗?您是否期望能够添加具有新后缀编号的新表并使其正常工作?

另一种可能的解决方案:

SELECT
     foo
FROM
     dbo.master m
WHERE
     (training_type = '001' AND EXISTS (SELECT * FROM dbo.training_data_001 WHERE foo_id = m.id)) OR
     (training_type = '002' AND EXISTS (SELECT * FROM dbo.training_data_002 WHERE foo_id = m.id)) OR
     (training_type = '003' AND EXISTS (SELECT * FROM dbo.training_data_003 WHERE foo_id = m.id)) OR
     (training_type = '004' AND EXISTS (SELECT * FROM dbo.training_data_004 WHERE foo_id = m.id)) OR
     (training_type = '005' AND EXISTS (SELECT * FROM dbo.training_data_005 WHERE foo_id = m.id))

如果你真的想从训练数据表中返回列,那么你可以使用类似的东西:

SELECT
     m.id,
     COALESCE(t1.my_col, t2.my_col, t3.my_col, t4.my_col, t5.my_col) AS my_col
FROM
     dbo.master m
LEFT OUTER JOIN dbo.training_data_001 t1 ON m.training_type = '001' AND t1.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_002 t1 ON m.training_type = '002' AND t2.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_003 t1 ON m.training_type = '003' AND t3.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_004 t1 ON m.training_type = '004' AND t4.foo_id = m.id
LEFT OUTER JOIN dbo.training_data_005 t1 ON m.training_type = '005' AND t5.foo_id = m.id
于 2008-12-09T20:43:11.503 回答
1

您只能在存储过程中使用动态 SQL 来执行此操作。如果您出于安全或其他原因不想即时执行此操作,还可以通过代码生成提前生成视图或存储过程。

于 2008-12-09T19:57:31.143 回答
1

如果表都是相同的结构,则跨表创建分区视图并连接视图。您需要对列(可能是日期)进行检查约束,以便查询优化器可以进行分区消除。

于 2008-12-09T20:03:54.033 回答
1

做这样的事情:

create view training_data_all as
select '001' as training_type, * from training_data_001
union all
select '002' as training_type, * from training_data_002
union all
select '003' as training_type, * from training_data_003
union all
select '004' as training_type, * from training_data_004
union all
select '005' as training_type, * from training_data_005

然后只需选择并加入到/从它:

SELECT foo FROM master WHERE id = ? 
INNER JOIN training_data_all
ON foo.id = training_data_all.foo_id
WHERE training_data_all.training_type = ${master.training_type}

如果表列表随着时间的推移而增长/缩小,您可以通过对系统表进行一些查找来根据存在的表动态编写相同的视图。

但是,这些都不是很有效。您能否以某个固定的时间间隔将此数据 ETL 到一个组合表中?

于 2008-12-09T20:22:34.277 回答