【问题标题】:SELECT FROM TABLES NAME LIKE从表名中选择喜欢
【发布时间】:2021-07-03 22:02:25
【问题描述】:

我在 SQL Server 数据库 (SSMS) 中有 1000 个表,并希望将 1000 个表中的选定列放入 1 个新表中。

我想做这样的事情

  1. 创建一个包含 a、b、c 列的新表

  2. 确定要从中选择数据的 1000 个表 - 要根据通配符之类的内容选择表名。

    在数据库中,有很多很多表,并且名称遵循类似的模式,例如ABC_0001, ABC_0002 ... ABC_1000, XYZ_0001, XYZ_0002, ... XYZ_1000 等...我只想选择以ABC 开头的表格..

  3. 从这 1000 个表中选择列 a、b、c,并将值插入在步骤 #1 中创建的表中

我是这样做的:

SELECT a, b, c FROM ABC_0001 UNION_ALL
SELECT a, b, c FROM ABC_0002 UNION_ALL
SELECT a, b, c FROM ABC_1000 
INSERT INTO NEW_TABLE

并且想做类似的事情

SELECT a, b, c FROM TABLE LIKE ABC_% 
INSERT INTO NEW_TABLE

【问题讨论】:

  • 您是否打算一次性在 SQL Management Studio 中运行它?如果是这样,可能你最简单的方法是动态地为来自“sys.sysobjects”的选择的每个结果构建选择语句 - 例如。 SELECT [name] FROM sys.sysobjects WHERE [name] LIKE 'ABC_%' AND [type] = 'U'
  • 感谢克雷格的回复,我是 SQL 的新手,所以不能完全遵循.. 但是我有所有表的列表,即 ABC_0001... ABC_1000.. 所以当输入 SELECT * FROM sys.tables WHERE ( name LIKE 'ABC_%' ) AND type = 'U' 我得到表名和对象 id 等等..但是我希望所有表中的数据合二为一..
  • 实际上没有一条语句可以确定所有可能的表名并一次性从所有这些表中进行选择。我的建议是查询“sysobjects”以确定与您的条件匹配的可用表名,但是您必须遍历每条记录并将每个表的相关选择语句增量添加到变量中,然后您可以执行最后的那条语句.....但是,如果您对 SQL 完全陌生,那么这对您来说可能是一个挑战。
  • 或许使用Excel(或类似的,例如Google Sheets)生成流水号序列,然后使用公式生成每个'SELECT a, b, c FROM ABC_ UNION ALL ' 语句 - 然后您可以复制并粘贴到 Management Studio 并执行查询。如果我有这样的一次性任务,我经常采用这种方法,需要生成一个通用的 SQL 语句,但是 Excel 可以轻松完成某种数字序列

标签: sql-server database select insert union-all


【解决方案1】:

您可以使用Dynamic SQLCURSOR OR WHILE LOOP 来实现这一点,我使用CURSOR 实现了它。如果您不想在新表中插入重复条目,请使用 UNION 而不是 UNION ALL


DROP TABLE IF EXISTS TABLE_NEW
CREATE TABLE TABLE_NEW (A VARCHAR,B VARCHAR, C VARCHAR) -- Modify according to your need
DECLARE @Sql NVARCHAR(MAX) = ''
,@TableName VARCHAR(500)
,@Id INT

DECLARE Table_Cursor CURSOR FOR 
SELECT 
ROW_NUMBER() OVER (ORDER BY TABLE_NAME ASC) Id
,TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
AND TABLE_NAME LIKE 'ABC_%'

OPEN Table_Cursor  
FETCH NEXT FROM Table_Cursor INTO @Id,@TableName 

WHILE @@FETCH_STATUS = 0  
BEGIN  
     IF(@Id = 1)
        BEGIN
            
            SET @Sql = @Sql + 'SELECT A, B, C FROM '+@TableName ----Modify the columns based on your column names
            SELECT @SQL
        END
     ELSE
        BEGIN
            SET @Sql = @Sql + ' UNION ALL SELECT A, B, C FROM '+@TableName --Modify the columns based on your column names
        END

     FETCH NEXT FROM Table_Cursor INTO @Id,@TableName
END 

CLOSE Table_Cursor  
DEALLOCATE Table_Cursor

INSERT INTO NEW_TABLE 
EXEC (@Sql)

根据您的新要求添加了以下答案。您可以检查table 中是否存在column,然后根据您得到的结果做出决定。我已经使用IIF()COL_LENGTH() 函数来实现这一点。

DROP TABLE IF EXISTS TABLE_NEW
CREATE TABLE TABLE_NEW (A VARCHAR,B VARCHAR, C VARCHAR) -- Modify according to your need
DECLARE @Sql NVARCHAR(MAX) = ''
,@TableName VARCHAR(500)
,@Id INT

DECLARE Table_Cursor CURSOR FOR 
SELECT 
ROW_NUMBER() OVER (ORDER BY TABLE_NAME ASC) Id
,TABLE_NAME 
FROM INFORMATION_SCHEMA.TABLES 
WHERE TABLE_TYPE = 'BASE TABLE' 
AND TABLE_NAME LIKE 'Temp%'

OPEN Table_Cursor  
FETCH NEXT FROM Table_Cursor INTO @Id,@TableName 

WHILE @@FETCH_STATUS = 0  
BEGIN  
     
     --Declare variables for all your columns here and assign the column name as the value

     DECLARE @A VARCHAR(100) = 'A', @B VARCHAR(100) = 'B',@C VARCHAR(100) = 'C'

     SELECT @A = IIF(COL_LENGTH(@TableName, @A)>0,@A,'NULL')
     SELECT @B = IIF(COL_LENGTH(@TableName, @B)>0,@B,'NULL')
     SELECT @C = IIF(COL_LENGTH(@TableName, @C)>0,@C,'NULL')

     IF(@Id = 1)
        BEGIN
            
            SET @Sql = @Sql + 'SELECT '+@A+' AS A, '+@B+' AS B, '+@C+' AS C FROM '+@TableName ----Modify the columns based on your column names
            SELECT @A AS A
        END
     ELSE
        BEGIN
            SET @Sql = @Sql + ' UNION ALL SELECT '+@A+' AS A, '+@B+' AS B, '+@C+' AS C FROM '+@TableName --Modify the columns based on your column names
        END

     FETCH NEXT FROM Table_Cursor INTO @Id,@TableName
END
CLOSE Table_Cursor  
DEALLOCATE Table_Cursor

INSERT INTO TABLE_NEW
SELECT @SQL



【讨论】:

  • 感谢 Annamalai.. 查询按预期工作.. 但是现在我遇到了没有选择变量的特定表,并且 sql 给出了变量丢失的错误。我们怎样才能克服这一点?我可以在最终输出中为这些变量取空值。
  • 如果只是一张表,可以在循环里面写一个条件来检查表名,缺失列的地方选择null
  • 引入了一组新的表,其中许多没有选择变量。有没有一种快速的方法来检查表中是否存在变量,如果没有,分配空值?
  • 是的,有一些方法可以检查表中是否存在列。新的一组表格是否遗漏了多个选定的列?
  • 是的..有些表​​缺少 1 列,有些表缺少 2 列或更多。每个表中缺少的列也不同..
【解决方案2】:

您可以执行以下操作:

-- use 'UNION' to select only distinct values, and UNION ALL if you want to select all rows

SELECT * 
    INTO [NEW_TABLE]
        FROM ABC_001
            UNION ALL
        SELECT * FROM ABC_002
            UNION ALL
        SELECT * FROM ABC_003
            UNION ALL
        -- and so on...
        SELECT * FROM ABC_999
        -- there's no need to use UNION on the last select

如果您真的不想键入所有 999 多个表,您可以编写一个存储过程以从名称与您所需模式匹配的表中进行选择。

参考资料:
https://www.w3schools.com/sql/sql_ref_union.asp
SELECT INTO USING UNION QUERY
SQL Server select data from 100+ tables

【讨论】:

  • @HKJ - Jeffrey 的建议与我的类似,即从“sysobjects”中选择以查找符合您条件的所有表。他对存储过程的建议是有道理的——因为,正如我所说,您将需要多行不同的语句来构建动态 SQL,然后执行它。存储过程成为数据库中的一个对象,您可以重复使用,如果这是您将来要再次执行的任务
  • 感谢 Craig 和 Jefferey,我正在尝试建议代码.. 我的表有 500+ 列,我必须从每个表中选择 100+ 列.. 所以将 SELECT [100+] 列写入 FROM TABLE 不可行.. 我们可以将所需的 100+ 列存储为别名并在每一行使用它吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-28
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 2021-09-03
  • 2013-12-30
  • 2013-04-15
相关资源
最近更新 更多