来自多个表的单列 SQL-SERVER 2014 Exprs

Single column from Multiple tables SQL-SERVER 2014 Exprs

我有一个包含 50 个 table 的数据库,它们具有相同的结构(相同的列名、类型)在 Created Date column 上聚集索引。这些 table 中的每一个都有大约 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

以上是数据库中table的例子。我需要一个可以快速运行并提取所有数据的 SQL。目前,我为此使用 UNION ALL,但完成报告需要很多时间。有没有另一种方法可以在不使用 UNION ALL 的情况下提取数据,例如

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

断章取义:我可以在结果中加入 table 名称吗?

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

这种动态 SQL 方法应该符合您的标准,它从架构中选择 table 名称并在运行时创建一个 SELECT 语句供其执行,并满足标准UNION ALL 中的每个 SELECT 语句都有一个 UNION ALL 然后我使用 STUFF 删除第一个。

DECLARE @SQL AS VarChar(MAX)
SET @SQL = ''

SELECT @SQL = @SQL + 'UNION ALL SELECT Name, Age, Gender FROM ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME LIKE 'Customer%'
SELECT @SQL = STUFF(@SQL,1,10,'')

EXEC (@SQL)

但是我不推荐使用这个,你应该按照人们在评论中建议的来重组你的数据。

内存优化下面的测试表与常规表中的相同数据相比,速度提高了 7 倍。示例是 50 个 100000 行的表。请仅 运行 在测试服务器上创建 filegroups/tables 等:

    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'