简体   繁体   English

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

[英]Single column from Multiple tables SQL-SERVER 2014 Exprs

I have a DB with 50 tables having the same structure (same column names, types) clustered Indexed on the Created Date column . 我有一个包含50个表的数据库,这些表具有相同的结构(相同的列名,类型),聚集在Created Date column Each of these tables have around ~ 100,000 rows and I need to pull all of them for some columns. 这些表中的每一个都有大约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

The above is an example of the tables in the DB. 上面是数据库中表的示例。 I need an SQL that runs quickly pulling all the data. 我需要一个能够快速提取所有数据的SQL。 Currently, I am using UNION ALL for this but it takes a lot of time for completing the report. 目前,我正在为此使用UNION ALL ,但是完成报告需要很多时间。 Is there another way for this where I can pull in data without using UNION ALL such as 还有另一种方法可以在不使用UNION ALL情况下提取数据,例如

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

Out of context: Can I pull in the table name in the result? 脱离上下文:我可以在结果中提取表名吗?

Thanks for any help. 谢谢你的帮助。 I've been putting my mind to this but I can't find a way to do it quicker. 我一直在考虑这一点,但我找不到更快的方法。

This dynamic SQL approach should meet your criteria, it selects table names from the schema and creates a SELECT statement at runtime for it to execute, and to meet the criteria of the UNION ALL each SELECT statement is given a UNION ALL then I use STUFF to remove the first one. 这种动态SQL方法应满足您的条件,它从模式中选择表名并在运行时创建一个SELECT语句以供执行,并满足UNION ALL的条件,每个SELECT语句STUFF赋予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)

However I do not recommend using this and you should do what people have suggested in the comments to restructure your data. 但是,我不建议您使用此方法,您应该执行人们在注释中建议的操作来重组数据。

Memory Optimising the test tables below gave a 7x speed increase compared to the same data in regular tables. 与常规表中的相同数据相比,下面的内存优化测试表使速度提高了7倍。 Samples are 50 tables of 100000 rows. 样本是100个行的50个表。 Please only run this on a test server as it creates filegroups/tables etc.: 请仅在测试服务器上运行此文件,因为它会创建文件组/表等:

    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'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM