多个表中的单列SQL-SERVER 2014 Exprs

时间:2018-06-20 10:51:41

标签: sql sql-server sql-server-2014 union union-all

我有一个数据库,其中有50个表,这些表具有相同的结构(相同的列名,类型),聚集在Created Date column上。这些表中的每一个都有大约100,000行,我需要将它们全部拉入某些列。

select * from customerNY

created date | Name | Age | Gender
__________________________________
25-Jan-2016  | Chris|  25 | M
27-Jan-2016  | John |  24 | M
30-Jan-2016  | June |  34 | F

select * from customerFL

created date | Name | Age | Gender
__________________________________
25-Jan-2016  | Matt |  44 | M
27-Jan-2016  | Rose |  24 | F
30-Jan-2016  | Bane |  34 | M

以上是数据库中表的示例。我需要一个能够快速提取所有数据的SQL。目前,我正在为此使用UNION ALL,但完成报告要花费很多时间。还有另一种方法可以在不使用UNION ALL的情况下提取数据,例如

select Name, Age, Gender from [:customerNY:customerFL:]

脱离上下文:我可以在结果中提取表名吗?

感谢您的帮助。我一直在考虑这一点,但是我找不到更快的方法。

2 个答案:

答案 0 :(得分:0)

这种动态SQL方法应满足您的条件,它从架构中选择表名称,并在运行时创建SELECT语句以使其执行并满足每个{{ 1}}语句被赋予UNION ALL,然后我使用STUFF删除第一个。

SELECT

但是,我不建议您使用此功能,您应该执行人们在注释中建议的操作来重组数据。

答案 1 :(得分:0)

内存优化下面的测试表与常规表中的相同数据相比,速度提高了7倍。样本是100个行的50个表。请仅在测试服务器上运行它,因为它会创建文件组/表等。

    USE [master]
    GO
    ALTER DATABASE [myDB] ADD FILEGROUP [MemOptData] CONTAINS MEMORY_OPTIMIZED_DATA 
    GO
    ALTER DATABASE [myDB] ADD FILE ( NAME = N'Mem', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL13.MSSQLSERVER\MSSQL\DATA' ) TO FILEGROUP [MemOptData] --Change Path for your version
    Go
    use [myDB]
    go
set nocount on
declare @loop1 int = 1
declare @loop2 int = 1
declare @NoTables int = 50
declare @noRows int = 100000
declare @sql nvarchar(max)

while @loop1 <= @NoTables
    begin
    set @sql = 'create table [MemCustomer' + cast(@loop1 as nvarchar(6)) + '] ([ID] [int] IDENTITY(1,1) NOT NULL,[Created Date] date, [Name] varchar(20), [Age] int, Gender char(1), CONSTRAINT [PK_Customer' + cast(@loop1 as nvarchar(6)) + '] PRIMARY KEY NONCLUSTERED 
(
    [ID] ASC
)) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA)'
    exec(@sql)
    while @loop2 <= @noRows
        begin
        set @sql = 'insert into [MemCustomer' + cast(@loop1 as nvarchar(6)) + '] ([Created Date], [Name], [Age], [Gender]) values (DATEADD(DAY, ROUND(((20) * RAND()), 0), DATEADD(day, 10, ''2018-06-01'')), (select top 1 [name] from (values(''bill''),(''steve''),(''jack''),(''roger''),(''paul''),(''ozzy''),(''tom''),(''brian''),(''norm'')) n([name]) order by newid()), FLOOR(RAND()*(85-18+1))+18, iif(FLOOR(RAND()*(2))+1 = 1, ''M'', ''F''))'
        --print @sql
        exec(@sql)
        set @loop2 = @loop2 + 1
        end
    set @loop2 = 1
    set @loop1 = @loop1 + 1
    end
    ;with cte as (
    Select * from MemCustomer1 
    UNION
    Select * from MemCustomer2 
    UNION
    ...
    UNION
    Select * from MemCustomer50
    )
    select * from cte where [name] = 'tom' and age = 27 and gender = 'F'