【问题标题】:Perform Union if table with these names exist如果存在具有这些名称的表,则执行联合
【发布时间】:2019-07-10 07:35:39
【问题描述】:

我有出勤数据库,每个月都会生成新表 像TRNS0419,TRNS0519,TRNS0619,TRNS0719。要合并数据,我使用了联合。 但是每个月我都手动输入表名,如果自动生成新表时自动选择数据,有什么办法吗,比如 TRNS0819

我尝试过使用 union all,但它没有使用不存在的表。

Select * from TRNS0419 union all Select * from TRNS0519
union all Select * from TRNS0619 union all Select * from TRNS0719

我的查询没有采用union all Select * from TRNS0819,因为这在 db 中不可用

它应该合并所有表并在查找临时表中显示结果。 请帮忙

【问题讨论】:

  • 最好的答案是:修复你的设计。为什么它不是一个带有额外列的表来存储 TRNS0719... 甚至是 DATE 列?
  • 首先,您必须声明一个 Store 过程并将您的查询放入其中,然后声明一个每月发生一次的作业并更改该 Store 过程
  • 你有固定的生成表的日期吗,最后有没有mmyy,用动态sql写一个存储过程?
  • 真正的答案是修复设计。如果您没有多个表,则不需要 UNION。多个表不会提高性能,它们只会使删除更容易。如果您需要为数据管理目的进行分区,请使用 SQL Server 自己的分区 - 自 20016 SP1 以来,它们在所有版本中都可用,包括 Express。在此之前,它们是企业功能。
  • 如果您坚持保留多个表(为什么??),您仍然需要日期列,并使用 CHECK 约束确保它仅包含该月的值。如果您按日期过滤并仅搜索允许该日期的表,SQL Server 的查询优化器将考虑它们。顺便说一句,分区也可以做同样的事情,没有额外的麻烦

标签: sql sql-server tsql sql-server-2008


【解决方案1】:

将以下代码包装在存储过程中:

DECLARE @DynamicTSQLStatement NVARCHAR(MAX);

SELECT @DynamicTSQLStatement = STUFF
(
    (
        SELECT N' UNION ALL SELECT * FROM ' + '[' + SCHEMA_NAME([schema_id]) + '].[' + [name] + ']'
        FROM [sys].[tables]
        WHERE [name] LIKE 'TRNS%'
        FOR XML PATH(''), TYPE
    ).value('.', 'NVARCHAR(MAX)')
    ,1
    ,10
    ,''
);

EXEC sp_executesql @DynamicTSQLStatement;

当从[sys].[tables] 视图中提取表名时,您可以添加更多过滤器。

【讨论】:

  • 如果有相似的表名,我会使用'TRNS[0-9][0-9][0-9][0-9]'
  • @Sami 当然。他可以根据需要更改过滤条件 - 例如,仅为特定模式提取表。
  • 更好的选择是使用所有表创建和更新一个视图,而不是每次都创建一个新查询。在添加新表时,此查询可用于每月生成和更新一次 VIEW 定义。
  • @gotqn 先生这是什么意思 ).value('.', 'NVARCHAR(MAX)') ,1 ,10 ,'' );
  • 非常感谢,这在我的场景中完美运行
猜你喜欢
  • 2011-08-16
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 1970-01-01
  • 2017-06-08
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
相关资源
最近更新 更多