我有一个数据库,其中有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:]
脱离上下文:我可以在结果中提取表名吗?
感谢您的帮助。我一直在考虑这一点,但是我找不到更快的方法。
答案 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'